Мы наблюдали странное поведение при компиляции следующего исходного кода:
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 одного типа». Следовательно, в нашей интерпретации должно быть возможно присвоить (или скопировать конструкцию) z из y.
Однако этот код не компилируется ни с gcc 4.8.1, ни с clang 3.3. Это ошибка в компиляторе или мы неправильно поняли стандарт?
Заранее спасибо,
Craffael и др .;)
Постскриптум Сообщение об ошибке 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 { };
Текущий стандарт не говорит об этом, но предполагается, что y и z имеют одинаковый тип. Для этого существует открытая основная рабочая группа: http://wg21.cmeerw.net/cwg/issue1286
Я думаю, что вы путаете тип и шаблон (или псевдоним шаблона). У тебя есть 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>
Различные типы.