Я узнал, что вы можете специализировать шаблон после, который он сначала использует, если вы используете его с использованием шаблона обертки. Простой пример:
#include <iostream>
template<typename T>
const char* templateImpl();
template<typename T>
const char* templateGetter() { return templateImpl<T>(); }
struct S{};
int main(){ std::cout << templateGetter<S>() << std::endl; return 0; }
template<>
const char* templateImpl<S>(){ return "S"; }
Это работает с каждым компилятором - я не удивлен, что MSVC компилирует его, поскольку он обрабатывает шаблоны по-разному, но GCC и clang позволяют это делать. Я думал, что стандарт требует, чтобы специализация происходила до первого использования, что в этом случае означало бы перед основной и ожидало, что они сообщают об ошибке.
Я что-то пропустил, соответствует ли этот код стандарту?
Чтобы уточнить, если я в основном меняю templateGetter<S>
на templateImpl<S>
, программа не будет компилироваться с сообщением об ошибке, которое я ожидал бы от этого тоже:
main.cpp: 14: 29: ошибка: специализация 'const char * templateImpl() [с T = S] 'после создания экземпляра