2016-07-11 7 views
3

Ich verstehe nicht, warum der folgende Code nicht kompiliert. Ich bekomme die gleichen Fehler mit GCC und Clang. Kann jemand erklären oder auf einen Teil des Standards verweisen, der erklären würde, warum p1 und p2 nicht vom selben Typ sind?C++ Klassen-Alias ​​kompiliert nicht als den gleichen Typ

struct TypeT {}; 

struct TypeU {}; 

template<typename T, typename U = TypeU> 
struct Foo {}; 


template<typename T, typename U> 
struct Bar 
{ 
}; 

template<typename T, template <typename> class U> 
struct FooBar 
{ 
}; 

template<typename T> 
using FooAlias1 = Foo<T>; 

template<typename T> 
using FooAlias2 = Foo<T>; 

template<typename T> 
void DoStuff(const T& p1, const T& p2) 
{ 
} 

int main(void) 
{ 
    FooBar<TypeT, FooAlias1> p1; 
    FooBar<TypeT, FooAlias2> p2; 
    DoStuff(p1, p2); 
} 

Dies ist die Ausgabe von gcc:

$ gcc --version 
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 

$ gcc -std=c++11 test.cpp 
test.cpp: In function ‘int main()’: 
test.cpp:34:19: error: no matching function for call to ‘DoStuff(FooBar<TypeT, FooAlias1>&, FooBar<TypeT, FooAlias2>&)’ 
    DoStuff(p1, p2); 
       ^
test.cpp:34:19: note: candidate is: 
test.cpp:26:6: note: template<class T> void DoStuff(const T&, const T&) 
void DoStuff(const T& p1, const T& p2) 
    ^
test.cpp:26:6: note: template argument deduction/substitution failed: 
test.cpp:34:19: note: deduced conflicting types for parameter ‘const T’ (‘FooBar<TypeT, FooAlias1>’ and ‘FooBar<TypeT, FooAlias2>’) 
    DoStuff(p1, p2); 

Und Klirren:

$ clang --version 
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4) 

$ clang -std=c++11 test.cpp 
test.cpp:34:5: error: no matching function for call to 'DoStuff' 
    DoStuff(p1, p2); 
    ^~~~~~~ 
test.cpp:26:6: note: candidate template ignored: deduced conflicting types for parameter 'T' ('FooBar<[...], template FooAlias1>' 
     vs. 'FooBar<[...], template FooAlias2>') 
void DoStuff(const T& p1, const T& p2) 
    ^
1 error generated. 
+2

Kein Standard Zitat auf meinem Ende, aber diese Aliase nicht Aliase geben, sind die Template-Aliase, und wenn ich macht in diesem Fall keine Garantie für Gleichheit richtig der Standard erinnern. – StoryTeller

Antwort

4

Von der Spezifikation, §14.4, zwei Typen gleichwertig sind, wenn ...

- ihre entsprechenden Template-Template-Argumente beziehen sich auf das gleiche Template e.

Aber Sie haben zwei verschiedene alias Vorlagen (§14.5.7). Sie sind keine Aliase.

  1. eine schablone Erklärung in dem die Erklärung ist eine Alias-Deklaration (Ziffer 7) erklärt, die Kennung zu eine Alias-Vorlage sein. Eine Aliasvorlage ist ein Name für eine Typenfamilie. Der Name der Alias-Vorlage lautet Vorlagenname.
+1

Insbesondere handelt es sich nicht um Vorlagenaliasnamen, sondern um Aliasvorlagen, da sie einen Aliasnamen vom Vorlagen-Typ anstelle eines Alias ​​für eine Vorlage bereitstellen. –