出于IO目的,我需要将字符串与各种类型关联。为此,我创建了一个模板类names
,该模板类专门用于我需要命名的每种类型。这是头文件:
template<typename T>
class names {};
template<>
class names<Index> {
public:
static const std::string name;
};
template<>
class names<Integer> {
public:
static const std::string name;
};
以及相应的源文件:
const std::string names<Index>::name = "Index";
const std::string names<Integer>::name = "Integer";
Index
和Integer
通过typedef
定义:
typedef std::ptrdiff_t Index;
typedef int Integer;
代码可以在我使用的macOS和Ubuntu计算机上编译并正常运行。但是,在Windows计算机上,std::ptrdiff_t
被定义为int
。然后,我得到以下错误:
In file included from lib/mixt_MixtComp.h:22:0,
from dummy.cpp:5:
lib/LinAlg/names.h:28:7: error: redefinition of 'class mixt::names<int>'
class names<Integer> {
^
lib/LinAlg/names.h:22:7: error: previous definition of 'class mixt::names<int>'
class names<Index> {
^
是否有避免此错误的方法?我可以使用C ++ 11。
答案 0 :(得分:3)
您有两个选择:
这里真正需要的是 strong typedef ,而不仅仅是瘦类型别名。您需要Index
和Integer
实际上是不同的类型,而不仅仅是仅仅是在两种情况下都可能相同的其他名称。
如果在使用这些类型进行算术时不介意一点麻烦,则可以使用范围限定的枚举:
enum class Index : std::ptrdiff_t {};
enum class Integer : int {};
现在,这两种类型是与您想要的类型截然不同但“继承”的,并且它们不会发生冲突,甚至不会相互隐式转换。 on your UNIXy platforms和on your Windows box都可以使用。
实际上,如果不是假定来使用这些类型,则实际上会发现作用域枚举的属性。
通常,我倾向于避免使用typedef
。它具有缩短长名的作用(尽管今天为了清楚起见,更喜欢使用using X = Y
),但是对于几乎其他所有情况,您都只是乞求在这里发现的麻烦。