Специализация члена класса шаблона без объявления в заголовке
У меня есть шаблонный класс, который я объявляю в заголовке с одним методом и без определения этого метода в заголовке. В файле .cc я определяю специализации этого методаникогда не объявляя их в шапке, В другом файле .cc я вызываю метод для разных параметров шаблона, для которых существуют специализации. Это выглядит так:
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;
}
Эта программа успешно компилирует и связывает с gcc 4.7.2 для всех стандартов C ++ (c ++ 98, gnu ++ 98, c ++ 11 и gnu ++ 11). Выход:
1
2
Это имеет смысл для меня. Поскольку модуль перевода main.cc не видит определенияbar()
или какие-либо его специализации, он ожидает звонкиbar()
использовать явные экземпляры неспециализированного определенияbar()
в каком-то другом переводческом блоке. Но поскольку искажение имен предсказуемо, специализации в foo.cc имеют те же имена символов, что и явные экземпляры неспециализированного определения, поэтому main.cc может использовать эти специализации без их объявления в этой единице перевода.
У меня такой вопрос: это случайность или это поведение предписано стандартом C ++? Другими словами, переносим ли этот код?
Самый важный предыдущий вопрос, который я мог найти, этоОбъявление специализации члена класса шаблона, но это не распространяется на этот конкретный случай.
(В случае, если вам интересно, почему это важно для меня, это потому, что я использую подобный код как своего рода таблицу поиска во время компиляции, и это намного короче, если я не объявляю специализации.)