Mam następujący C++ kod:Dlaczego poniższy kod powoduje wystąpienie szablonu?
//Define to 1 to make it work
#define WORKS 0
#if WORKS
template< typename T > struct Foo;
#else
template< typename T >
struct Foo {
T t;
};
#endif
class Bar; //Incomplete type
void fFooBar(Foo<Bar> const & foobar) { }
void f(Foo<Bar> const & foobar) {
fFooBar(foobar);
}
int main() {
return 0;
}
Jeśli działa jest definiowana jako 0 (szablon struktura jest zdefiniowana) kod nie skompilować, ponieważ próbuje instancję w fFooBar(foobar);
i nie powiedzie się, ponieważ Bar
jest niekompletny.
Jeśli WORK jest zdefiniowany jako 1 (szablon struktury jest niezdefiniowany), kod się kompiluje.
Zgodnie ze standardem szablon nie powinien być inicjowany, chyba że wymagany jest kompletny typ (co nie ma miejsca w przypadku const&
) lub zmieniłby semantykę kodu (co również nie ma miejsca, i againt, to samo powinno się stać, jeśli szablon nie został zdefiniowany).
Co dziwne, program można skompilować, usuwając informacje z kompilatora. Ale fakt, że MSVC, gcc i clang wszystkie robią to samo powoduje, że myślę, że musi istnieć ku temu powód.
ADL, myślę. Podobny problem, jak http://stackoverflow.com/questions/25925551/gcc-and-clang-implicitly-instantiate-template-arguments-during-operator-overload –
@ T.C. [temp.inst]/7? – Columbo
@Columbo Rzeczywiście. –