Рассмотрим простой шаблон специализации:Частичная специализация шаблона с параметрами нетиповых: GCC против МСВС
template<typename T, size_t I>
struct S {};
template<typename T>
struct S<T, std::tuple_size<T>::value> {};
GCC не компилирует его, так как он использует параметр шаблона T
в шаблоне аргумента std::tuple_size<T>::value
:
error: template argument 'std::tuple_size<_Tp>::value' involves template parameter(s)
Теперь давайте заменим T
с typename std::remove_reference<T>::type
в tuple_size
аргумент шаблона:
// Using primary structure template from previous example.
template<typename T>
struct S<T, std::tuple_size<typename std::remove_reference<T>::type>::value> {};
Этот код по-прежнему использует параметр шаблона в аргументе шаблона, но GCC компилирует его без каких-либо ошибок или предупреждений. Зачем?
Теперь, если мы попытаемся собрать второй пример использования МСВС с /std:c++latest
флагом, он останавливается с ошибкой C2755:
non-type parameter of a partial specialization must be a simple identifier
Что это странное ограничение? Я хочу прекратить рекурсию времени компиляции, когда I
станет равным размеру кортежа.
Так кто же из них не прав: MSVS или GCC?
Обратите внимание, что МСВС сообщает об ошибке, даже без какой-либо конкретизации шаблона, в то время как GCC работает отлично со всеми этими экземплярами:
S<std::tuple<int, float>, 9> s1;
S<std::tuple<int, float>, 2> s2;
S<int, 42> s3;
Я использую МСВС Community 2015 Update 3 с его компилятор по умолчанию и GCC 6.2.1.
Tried Clang 3.8.0. Он не компилируется как фрагментов с ошибкой, подобными сообщениями GCC в:
error: non-type template argument depends on a template parameter of the partial specialization