通用类型别名,它们互不兼容 [英] generic type alias, which are incompatible to each other

查看:51
本文介绍了通用类型别名,它们互不兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构造某种通用类型别名",这意味着我想将一个类型定义为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆