plantillas - ¿El alias de plantilla de C++ 11 como argumento de plantilla de plantilla lleva a un tipo diferente?
plantillas c++ (2)
Hemos observado un comportamiento extraño en la compilación del siguiente código fuente:
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
}
Este es un ejemplo ligeramente modificado tomado de la propuesta estándar de c ++ 11 para alias de plantillas: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf (vea la página 4 ) También tenga en cuenta que la propuesta "declara que y y z son del mismo tipo". En nuestra interpretación, por lo tanto, debería ser posible asignar (o copiar la construcción) z desde y.
Sin embargo, este código no se compila con gcc 4.8.1 ni con clang 3.3. ¿Es esto un error en el compilador o entendimos mal el estándar?
Gracias de antemano, Craffael et al;)
PS El mensaje de error de Clang es:
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 { };
Creo que estás confundiendo un tipo y una plantilla (o un alias de plantilla). Tienes Y
, que es una plantilla y Z
, que es otra. Si crees que Y
== Z
, estás equivocado. Solo si los convierte en tipos, esos tipos son los mismos, por ejemplo, Y<int>
es el mismo tipo que Z<int>
. En tu ejemplo:
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
}
En su código original, los mencionó con X<Y>
y X<Z>
, pero como Y
no es lo mismo que Z
, también lo son X<Y>
y X<Z>
tipos diferentes.
El estándar actual no lo dice, pero la intención es que y y z sean del mismo tipo. Hay un problema abierto del Grupo de trabajo central para esto: http://wg21.cmeerw.net/cwg/issue1286