2015-04-17 17 views
14

Dlaczego następuje skompilować z clang ale nie z g++ 4.9Domyślnie argumentem za częściową specjalizację [Clang tak, GCC nie]

#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 ++ nie znaleźć odpowiednią specjalizację i narzeka z „niekompletny rodzaj". Zastanawiam się, ponieważ domyślnym argumentem typename T3 = int powinien ubiegać się o specjalizacji (czy też mają zastosowanie tylko do pełnej specjalizacji?)

+10

Ponieważ używasz 'niepodpisany int' zamiast' std :: size_t'. W tym drugim kompilatory akceptują program. – dyp

+1

Powiązane: http://stackoverflow.com/q/21740896/ – dyp

+1

Może być https://llvm.org/bugs/show_bug.cgi?id=16279 – dyp

Odpowiedz

4

Szablony A<T1, T2, T3> i A<T1, T2> nie są kompletne zdefiniowane, więc nie można użyć swoich członków, można rozwiązać problem zdefiniowania tego szablony w ten sposób:

#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; 
} 

Innym dobrym przykładem specjalizacji bardziej prosta:

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; 
} 

Jak @dys powiedzieć na własną komentarzu przy użyciu std::size_t zamiast unsigned int utwory:

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

Nie sądzę, że to odpowiedź , asnwer powinien być komentarzem @ dyp. Problem polega na tym, że pasuje do pierwszego prototypu (który jest niekompletny tak), ponieważ dopasowanie szablonu jest oczywiście pedantyczne w odniesieniu do używanych typów -> '' szablon std :: array'' – Gabriel

+0

@dyp są naprawdę dobre, używając 'std :: size_t' zamiast tego' unsigned int' działa poprawnie. –

Powiązane problemy