2013-10-11 9 views
6

Wir haben ein seltsames Verhalten bei der Erstellung des follwing Quellcodes beobachtet:C++ 11 Vorlage Alias ​​als Vorlage Vorlage Argument führt zu anderen Typ?

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 
} 

Dies ist ein leicht modifiziertes Beispiel aus dem c genommen ++ 11 Standardvorschlag für die Template-Aliase: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf (Siehe Seite 4) Beachten Sie auch, dass der Vorschlag "deklariert, dass y und z vom selben Typ sind". In unserer Interpretation sollte es daher möglich sein, z aus y zuzuordnen (oder zu kopieren).

Dieser Code wird jedoch weder mit gcc 4.8.1 noch mit clang 3.3 kompiliert. Ist das ein Fehler im Compiler oder haben wir den Standard falsch verstanden?

Dank im Voraus, craffael et al;)

P.S. Die Clang Fehlermeldung lautet:

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

'Y' und' Z' sind andere * Template-Namen *, als solche ergeben sie verschiedene Instanziierungen mit 'X'. Siehe § 14.5.7/1. – Xeo

Antwort

8

Der aktuelle Standard sagt es nicht, aber die Absicht ist, dass y und z den gleichen Typ haben. Es gibt ein offenes Core Working Group-Problem dafür: http://wg21.cmeerw.net/cwg/issue1286

+0

Vielen Dank, das war in der Tat der fehlende Schlüssel. Ich habe gerade den Standard gescannt und konnte nicht wirklich einen Hinweis finden, dass mein Code schlecht geformt ist. Ich habe jedoch festgestellt, dass das Beispiel aus dem Vorschlag leicht zu dem von Daniel Frey vorgeschlagenen geändert wurde. Diese Art von Hinweisen, dass mein Code ist wahrscheinlich schlecht gebildet, aber es ist nicht explizit gesagt (das ist meine Interpretation) Wie auch immer ich hoffe, Ausgabe 1286 macht es in den nächsten Standard ... – craffael

+0

+1 Interessant, so meine Antwort * war * korrekt, aber das wird sich (hoffentlich) ändern. Gut zu wissen! –

+1

In der Ausgabe 1244 wurde festgestellt, dass es keine Formulierung für dieses Beispiel gab, daher aktualisierte die Kernarbeitsgruppe das Beispiel. Gaby Dos Reis bemerkte jedoch, dass die Absicht des ursprünglichen Beispiels darin bestehe, wohlgeformt zu sein. Daher wurde das Problem 1286 geöffnet, um den normativen Text zu aktualisieren (und das Beispiel zurück zu ändern). – cmeerw

3

Ich denke, Sie eine Art verwirrend sind und eine Vorlage (oder eine Vorlage alias). Sie haben Y, die eine Vorlage ist und Z, die eine andere ist. Wenn Sie denken, dass Y == Z, Sie irren sich. Nur wenn Sie sie in Typen umwandeln, sind diese Typen die gleichen, z. Y<int> ist der gleiche Typ wie Z<int>. In Ihrem Beispiel:

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 
} 

In Ihrem ursprünglichen Code bezeichnete man sie mit X<Y> und X<Z>, aber als Y nicht die gleichen wie Z ist, sind so X<Y> und X<Z> verschiedene Typen.

+0

Ich bin mir bewusst, dass Typen und Vorlagen nicht identisch sind und ich stimme völlig zu, dass Ihr Beispiel kompilieren sollte. Jedoch scheint es aus dem Standard unklar zu sein, ob mein Code schlecht geformt ist (siehe Antwort von cmeerw). – craffael