通用类型别名,它们互不兼容 [英] generic type alias, which are incompatible to each other
问题描述
我正在尝试构造某种通用类型别名",这意味着我想将一个类型定义为 int
,但是要使用一个通用类型参数,这会使它与的实例不兼容.其他类型.
I am trying to construct some kind of "generic type alias", meaning I want to define a type as int
for example, but with a generic type argument which then makes it incompatible with instances of other types.
我尝试使用别名模板执行此操作:
I tried doing this with alias templates:
template <typename T>
using NumberWithSemantics = int;
但是与此有关的问题是,所有实例化,无论类型为 T
,都被认为是相等的,例如:
But the problem with this is that all instantiations, no matter the type T
, are considered equal, for example:
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
}
是否有一种方法可以定义某种通用类型别名,以防止混合使用不同的模板实例?
Is there a way to define some kind of generic type alias that disallows mixing different template instantiations?
推荐答案
C ++具有类型别名,但是只有弱类型别名.当你说
C++ has type aliasing, but it is only weak type aliasing. When you say
typedef int MyType;
或
using MyType = int;
您告诉编译器,每当看到 MyType
时,都假装您刚刚看到了 int
."这样, MyType i
和 int i
之间完全没有区别.都创建一个名为 int
的名为 i
的变量.使用模板声明 using
并没有帮助;所有这些类型均等效为 int
.
you tell the compiler, "whenever you see MyType
, pretend you had just seen int
instead". There is then no difference at all between MyType i
and int i
; both create a variable named i
of type int
. Making the using
declaration a template doesn’t help; all of the types equivalently mean int
.
您想要做的是创建一个实际的新类型.为此,您需要使用 struct
或 class
声明它,而不仅仅是 using
.即使它们看起来相同,thpe系统也会将以此方式创建的每个新类型都视为一个单独的类型.通过扩展,如果您创建模板 struct
,则每个实例化都是一种新类型.
What you want to do is create an actual new type. To do this, you need to declare it with struct
or class
, not just using
. Even if they look the same, the thpe system will treat each new type created this way as a separate type; by extension, if you make a template struct
, each instantiation will be a new type.
因此,最小的可能解决方案是:
Therefore, the minimum potential solution would be:
template <typename T>
struct NumberWithSemantics { int i; };
然后,您可以将 NumberWithSemantics< A>
和 NumberWithSemantics< B>
用作不同的类型.但是,您将需要继续说 .i
才能获得实际值,这会使您的代码更难阅读.有多种解决方法,我建议阅读有关Fluent C ++的强类型"系列的这一部分.
Then you can use NumberWithSemantics<A>
and NumberWithSemantics<B>
as different types. However, you will need to keep saying .i
to get the actual value out, which can make your code harder to read. There are various possible ways to get around that, for which I recommend reading this part of the Strong Types series on Fluent C++.
这篇关于通用类型别名,它们互不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!