泛型类型别名,它们彼此不兼容

时间:2018-06-05 21:49:53

标签: c++ templates c++17 generic-programming 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
}

有没有办法定义某种不允许混合不同模板实例的泛型类型别名?

1 个答案:

答案 0 :(得分:3)

C ++具有类型别名,但它只是类型别名。当你说

typedef int MyType;

using MyType = int;

你告诉编译器,“每当你看到MyType时,假装你刚刚看到int”。那么MyType iint i之间没有区别;两者都创建一个名为i的{​​{1}}类型的变量。将int声明设为模板无济于事;所有类型都等同于using

您要做的是创建一个实际的新类型。为此,您需要使用intstruct声明它,而不仅仅是class。即使它们看起来相同,但是thpe系统会将以这种方式创建的每种新类型视为一种单独的类型;通过扩展,如果您创建模板using,则每个实例化都将是一个新类型。

因此,最小的潜在解决方案是:

struct

然后,您可以将template <typename T> struct NumberWithSemantics { int i; }; NumberWithSemantics<A>用作不同的类型。但是,您需要继续说NumberWithSemantics<B>以获取实际值,这会使您的代码更难以阅读。有各种可能的解决方法,我建议在Fluent C ++上阅读强类型系列的this part