考虑这个简单的模板专业化:模板偏特非类型参数:GCC VS MSVS
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)
现在,让我们在tuple_size
模板参数与typename std::remove_reference<T>::type
替换T
:
// Using primary structure template from previous example.
template<typename T>
struct S<T, std::tuple_size<typename std::remove_reference<T>::type>::value> {};
该代码仍然在模板参数中使用模板参数,但GCC编译时没有任何错误或警告。为什么?
non-type parameter of a partial specialization must be a simple identifier
这是什么奇怪的限制:
现在,如果我们试图编译使用MSVS的第二个例子是/std:c++latest
标志,它与错误C2755停止?当I
等于元组大小时,我想停止编译时递归。
那么他们是谁错了:MSVS还是GCC?
注意MSVS即使没有任何模板实例报告错误,而GCC正常工作与所有这些实例:
S<std::tuple<int, float>, 9> s1;
S<std::tuple<int, float>, 2> s2;
S<int, 42> s3;
我使用MSVS社区2015年更新3与它的默认编译器和GCC 6.2.1。
尝试铿锵3.8.0。它不具有类似于GCC的消息的错误编译两个片段:
error: non-type template argument depends on a template parameter of the partial specialization