9

我们在以下源代码的编译中观察到了一个奇怪的行为:

template<template<class> class TT> struct X { };
template<class> struct Y { };
template<class T> using Z = Y<T>;

int main() {
  X<Y> y;
  X<Z> z;
  z = y; // it fails here
}

这是取自模板别名的 c++11 标准提案的一个稍作修改的示例:http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf (参见第 4 页) 另请注意,该提案“将 y 和 z 声明为同一类型”。因此,在我们的解释中,应该可以从 y 分配(或复制构造)z。

但是,此代码不能使用 gcc 4.8.1 和 clang 3.3 编译。这是编译器中的错误还是我们误解了标准?

在此先感谢 craffael 等人 ;)

PS Clang 错误消息是:

error: no viable overloaded '='

note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'X<template Y>' to 'const X<template Z>' for 1st argument
template<template<class> class TT> struct X { };

note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'X<template Y>' to 'X<template Z>' for 1st argument
template<template<class> class TT> struct X { };
4

2 回答 2

11

目前的标准并没有这么说,但意图是 y 和 z 具有相同的类型。有一个开放的核心工作组问题:http ://wg21.cmeerw.net/cwg/issue1286

于 2013-10-11T10:22:12.443 回答
3

我认为您混淆了类型和模板(或模板别名)。你有Y, 这是一个模板,Z, 这是另一个模板。如果您认为Y== Z,那您就错了。仅当您将它们转换为类型时,这些类型才相同,例如Y<int>Z<int>. 在您的示例中:

template<class T> struct X { };

template<class> struct Y { };
template<class T> using Z = Y<T>;

int main() {
  X<Y<int>> y;
  X<Z<int>> z;
  z = y; // works
}

在您的原始代码中,您使用X<Y>and来引用它们X<Z>,但 asY与不同类型Z的不同。X<Y>X<Z>

于 2013-10-11T09:11:07.127 回答