【问题标题】:C++ class alias does not compile as same typeC++ 类别名不编译为相同类型
【发布时间】:2016-07-11 15:59:19
【问题描述】:

我不明白为什么下面的代码无法编译。我使用 GCC 和 Clang 都遇到了同样的错误。有人可以解释或指出标准的一部分来解释为什么 p1p2 不是同一类型吗?

struct TypeT {};

struct TypeU {};

template<typename T, typename U = TypeU>
struct Foo {};


template<typename T, typename U>
struct Bar
{
};

template<typename T, template <typename> class U>
struct FooBar
{
};

template<typename T>
using FooAlias1 = Foo<T>;

template<typename T>
using FooAlias2 = Foo<T>;

template<typename T>
void DoStuff(const T& p1, const T& p2)
{
}

int main(void)
{
    FooBar<TypeT, FooAlias1> p1;
    FooBar<TypeT, FooAlias2> p2;
    DoStuff(p1, p2);
}

这是 gcc 的输出:

$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

$ gcc -std=c++11 test.cpp
test.cpp: In function ‘int main()’:
test.cpp:34:19: error: no matching function for call to ‘DoStuff(FooBar<TypeT, FooAlias1>&, FooBar<TypeT, FooAlias2>&)’
     DoStuff(p1, p2);
                   ^
test.cpp:34:19: note: candidate is:
test.cpp:26:6: note: template<class T> void DoStuff(const T&, const T&)
 void DoStuff(const T& p1, const T& p2)
      ^
test.cpp:26:6: note:   template argument deduction/substitution failed:
test.cpp:34:19: note:   deduced conflicting types for parameter ‘const T’ (‘FooBar<TypeT, FooAlias1>’ and ‘FooBar<TypeT, FooAlias2>’)
     DoStuff(p1, p2);

还有叮当声:

$ clang --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)

$ clang -std=c++11 test.cpp
test.cpp:34:5: error: no matching function for call to 'DoStuff'
    DoStuff(p1, p2);
    ^~~~~~~
test.cpp:26:6: note: candidate template ignored: deduced conflicting types for parameter 'T' ('FooBar<[...], template FooAlias1>'
      vs. 'FooBar<[...], template FooAlias2>')
void DoStuff(const T& p1, const T& p2)
     ^
1 error generated.

【问题讨论】:

  • 我没有标准引用,但那些别名不是类型别名,它们是模板别名,如果我没记错的话,标准在这种情况下不保证相等。

标签: c++ templates gcc clang


【解决方案1】:

根据规范,§14.4,如果...,两种类型是等价的

——它们对应的模板模板参数引用同一个模板。

但是您有两个不同的别名模板(第 14.5.7 节)。它们不是类型别名。

  1. 声明是别名声明(第 7 条)的模板声明将标识符声明为 是一个别名模板。别名模板是一系列类型的名称。别名模板的名称是 模板名称。

【讨论】:

  • 特别是,它们不是模板别名而是别名模板,因为它们提供模板化类型别名而不是模板别名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
相关资源
最近更新 更多