Mam klasę szablonu, którą deklaruję w nagłówku z jedną metodą i bez definicji tej metody w nagłówku. W pliku .cc definiuję specjalizacje tej metody , nigdy nie deklarując ich w nagłówku. W innym pliku .cc wywołuję metodę dla różnych parametrów szablonu, dla których istnieją specjalizacje. Wygląda to tak:Specjalizacja członka klasy szablonu bez deklaracji w nagłówku
Foo.h:
template<typename T>
class Foo {
public:
static int bar();
};
foo.cc:
#include "foo.h"
template<>
int Foo<int>::bar() {
return 1;
}
template<>
int Foo<double>::bar() {
return 2;
}
main.cc:
#include <iostream>
#include "foo.h"
int main(int argc, char **argv) {
std::cout << Foo<int>::bar() << std::endl;
std::cout << Foo<double>::bar() << std::endl;
return 0;
}
Ten program kompiluje i łączy z powodzeniem z gcc 4.7.2 dla wszystkich standardów C++ (C++ 98, gnu ++ 98, C++ 11 i gnu ++ 11). Dane wyjściowe to:
1
2
To ma dla mnie sens. Ponieważ jednostka tłumaczeniowa main.cc nie widzi definicji bar()
ani żadnych jej specjalizacji, oczekuje ona, że wywołania do bar()
będą wykorzystywać jawne tworzenie nieokreślonej definicji bar()
w jakiejś innej jednostce tłumaczeniowej. Ale ponieważ nazwa "mangling" jest przewidywalna, specjalizacje w foo.cc mają te same nazwy symboli co jawne instancje o nieokreślonej definicji, więc main.cc może korzystać z tych specjalizacji bez zadeklarowania ich w tej jednostce tłumaczeniowej.
Moje pytanie brzmi: czy to jest wypadek, czy też takie zachowanie jest wymagane przez standard C++? Innymi słowy, czy ten kod jest przenośny?
Najważniejszym wcześniejszym pytaniem, które mogłem znaleźć, jest Declaration of template class member specialization, ale nie obejmuje tego konkretnego przypadku.
(W przypadku, gdy zastanawiacie się, dlaczego to ma dla mnie znaczenie, to dlatego, że używam tego kodu jako pewnego rodzaju tabeli przeglądowej w czasie kompilacji i jest znacznie krótszy, jeśli nie deklaruję specjalizacji .)
To raczej dobre pierwsze pytanie! Myślę, że kompilator IBM pozwala zadeklarować swoje specjalizacje za pomocą słowa kluczowego extern, ale nigdy nie zrobił tego sam. –