2016-04-07 35 views
8

Ten kod kompiluje z brzękiem3.7.1 (bez diagnostyki), ale nie z GCC5.3.0 (live example):Szablon kompilacja błąd przyjaźń z GCC, ale nie z brzękiem

#include <iostream> 

template<typename T> 
struct A { 
    void foo() 
    { 
     static_cast<T*>(this)->implementation(); 
    } 
}; 

struct Crtp : A<Crtp> { 
    template<typename T> 
    friend struct A; 
private: 
    void implementation() { std::cout << "implementation()\n"; } 
}; 

int main() 
{ 
    Crtp c; 
    c.foo(); 
} 
komunikat o błędzie

GCC jest następujący:

main.cpp:13:16: error: specialization of 'A' after instantiation friend struct A;

Który z nich ma rację, a dlaczego? Czy to błąd GCC/clang?

Odpowiedz

4

Wydaje się być starym błędem g ++ (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52625).

Zgłoszone i nigdy nie poprawił, jeśli dobrze rozumiem,

+1

Jesteś poprawne. Co więcej, wydaje się, że gcc ma wiele [problemów znajomych] (https://gccnu.nu/bugzilla/showdependencytree.cgi?id=65608&hide_resolved=1). – akakatak

3

Myślę, że to błąd gcc.

Deklaracja klasy przyjaciela szablonu jest tylko deklaracją, a nie definicją. Redeclaracja szablonu klasy jest dozwolona, ​​chyba że ma inny klucz klasy (patrz N4527 14.5.1.4).

Specjalizacja lub tworzenie instancji może wystąpić dwa razy lub więcej. Jednoznaczna specjalizacja może wystąpić tylko raz (N4527 14.7.3.6).

Następnie diagnostyka gcc jest nieparzysta, ponieważ nie ma wyraźnej specjalizacji.

0

Mamy pewne nazwa szablonu kursy Rozdzielczość:

struct Crtp : A<Crtp> { 
    A x; // A refers to A<Crtp> 
}; 

Teraz rzeczy są jasne:

template<typename T> friend struct A; 

odnosi się do:

template<typename T> friend struct A<Crtp>; 

która jest ... tak, częściowa specjalizacja (naprawdę podchwytliwa).

Więc GCC jest tutaj poprawny.

Co tak naprawdę potrzebujesz to:

struct Crtp : A<Crtp> { 
friend struct A; 
private: 
    void implementation() { std::cout << "implementation()\n"; } 
};