我们在编写下面的源代码时发现了一个奇怪的行为:
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等人;)
P.S。 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 { };
答案 0 :(得分:11)
目前的标准并没有这样说,但目的是y和z具有相同的类型。有一个开放的核心工作组问题:http://wg21.cmeerw.net/cwg/issue1286
答案 1 :(得分: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>
和X<Z>
引用了它们,但由于Y
与Z
不同,X<Y>
和X<Z>
也是如此{{1}}种不同的类型。