2015-04-17 8 views
14

Warum das mit clang folgenden kompilieren, aber nicht mit g++ 4.9Standardargument für die partielle Spezialisierung [Clang yes, no GCC]

#include <array> 

template< typename T1, typename T2 , typename T3 = int> 
struct A; 

template<typename T, unsigned int N, typename T2, typename T3> 
struct A< std::array<T,N>, T2, T3 > { 
    int a; 
}; 

int main() 
{ 
    A< std::array<int,10>, double> a; 
    a.a +=3; 
} 

http://coliru.stacked-crooked.com/a/c7800f49ba5aac43

g ++ nicht eine geeignete Spezialisierung und klagt mit „unvollständig findet Art". Ich frage mich, da das Standardargument typename T3 = int für die Spezialisierung gelten sollte (oder ist es nur für die vollständige Spezialisierung bewerben?)

+10

Weil Sie mit 'unsigned int' statt' std :: size_t'. Mit letzterem akzeptieren beide Compiler das Programm. – dyp

+1

Related: http://stackoverflow.com/q/21740896/ – dyp

+1

Könnte sein https://llvm.org/bugs/show_bug.cgi?id=16279 – dyp

Antwort

4

Die Vorlagen A<T1, T2, T3> und A<T1, T2> nicht definiert sind komplett, so dass Sie nicht Ihre Mitglieder nutzen können, können Sie lösen das Problem dieser Definition von Vorlagen auf diese Weise:

#include <array> 

template< typename T1, typename T2 , typename T3 = int> 
struct A { 
    int a; 
}; 

template<typename T, unsigned int N, typename T2, typename T3> 
struct A< std::array<T,N>, T2, T3 > { 
    int a; 
}; 

int main() 
{ 
    A< std::array<int,10>, double> a; 
    a.a +=3; 
} 

Ein weiteres schönes Beispiel für die Spezialisierung einfacher:

template<typename T, unsigned int N> 
struct A { 
    T a = N; 
}; 

template<unsigned int N> 
struct A<int, N> { 
    int a = 2*N; 
}; 

#include <iostream> 
using namespace std; 

main() { 
    A<float, 30> af; 
    A<int, 30> ai; 
    cout << af.a << endl << ai.a << endl; 
} 

Wie @dys sagen auf Ihrem Kommentar mit std::size_t statt unsigned int Werke:

template< typename T1, typename T2 , typename T3 = int> 
struct A; 

template<typename T, std::size_t N, typename T2, typename T3> 
struct A< std::array<T,N>, T2, T3 > { 
     T3 a = N; 
     int b; 
}; 

int main() 
{ 
     A< std::array<int,10>, double> a; 
     a.a +=3; 

     A< std::array<int,10>, double, int> b; 
     b.b +=3; 
} 
+0

Ich glaube nicht, dass das die Antwort ist , sollte der asnwer @ dyps Kommentar sein. Das Problem ist, dass es mit dem ersten Prototyp übereinstimmt (was ja unvollständig ist), weil das Template-Matching offensichtlich um die verwendeten Typen pedantisch ist -> '' Template std :: array'' – Gabriel

+0

@dyp sind wirklich richtig, mit 'std :: size_t' anstelle von' unsigned int' funktioniert gut. –

Verwandte Themen