通用类型别名,它们彼此不兼容
generic type alias, which are incompatible to each other
我正在尝试构建某种类型的 "generic type alias",这意味着我想将类型定义为 int
,但是使用泛型类型参数使其与其他类型的实例不兼容类型。
我尝试使用别名模板执行此操作:
template <typename T>
using NumberWithSemantics = int;
但这样做的问题是所有实例化,无论类型 T
,都被认为是相等的,例如:
struct A {};
struct B {};
NumberWithSemantics<A> getThing() {
return 14;
}
int processDifferentThing(NumberWithSemantics<B> b) {
return b * 3;
}
int main() {
auto a = getThing();
return processDifferentThing(a); // unfortunately compiles just fine
}
有没有办法定义某种通用类型别名,不允许混合不同的模板实例化?
C++有类型别名,但只是弱类型别名。当你说
typedef int MyType;
或
using MyType = int;
你告诉编译器,“每当你看到 MyType
时,假装你刚刚看到 int
”。那么 MyType i
和 int i
之间完全没有区别;两者都创建了一个名为 i
且类型为 int
的变量。使 using
声明成为模板没有帮助;所有类型都等价地表示 int
.
您要做的是创建一个实际的新类型。为此,您需要使用 struct
或 class
声明它,而不仅仅是 using
。即使它们看起来相同,类型系统也会将以这种方式创建的每个新类型视为一个单独的类型;推而广之,如果您制作模板 struct
,每个实例化都将是一个新类型。
因此,最小可能的解决方案是:
template <typename T>
struct NumberWithSemantics { int i; };
然后你可以使用NumberWithSemantics<A>
和NumberWithSemantics<B>
作为不同的类型。但是,您需要不断地说 .i
才能得到实际值,这会使您的代码更难阅读。有多种可能的方法来解决这个问题,为此我建议阅读关于 Fluent C++ 的强类型系列的 this part。
我正在尝试构建某种类型的 "generic type alias",这意味着我想将类型定义为 int
,但是使用泛型类型参数使其与其他类型的实例不兼容类型。
我尝试使用别名模板执行此操作:
template <typename T>
using NumberWithSemantics = int;
但这样做的问题是所有实例化,无论类型 T
,都被认为是相等的,例如:
struct A {};
struct B {};
NumberWithSemantics<A> getThing() {
return 14;
}
int processDifferentThing(NumberWithSemantics<B> b) {
return b * 3;
}
int main() {
auto a = getThing();
return processDifferentThing(a); // unfortunately compiles just fine
}
有没有办法定义某种通用类型别名,不允许混合不同的模板实例化?
C++有类型别名,但只是弱类型别名。当你说
typedef int MyType;
或
using MyType = int;
你告诉编译器,“每当你看到 MyType
时,假装你刚刚看到 int
”。那么 MyType i
和 int i
之间完全没有区别;两者都创建了一个名为 i
且类型为 int
的变量。使 using
声明成为模板没有帮助;所有类型都等价地表示 int
.
您要做的是创建一个实际的新类型。为此,您需要使用 struct
或 class
声明它,而不仅仅是 using
。即使它们看起来相同,类型系统也会将以这种方式创建的每个新类型视为一个单独的类型;推而广之,如果您制作模板 struct
,每个实例化都将是一个新类型。
因此,最小可能的解决方案是:
template <typename T>
struct NumberWithSemantics { int i; };
然后你可以使用NumberWithSemantics<A>
和NumberWithSemantics<B>
作为不同的类型。但是,您需要不断地说 .i
才能得到实际值,这会使您的代码更难阅读。有多种可能的方法来解决这个问题,为此我建议阅读关于 Fluent C++ 的强类型系列的 this part。