【发布时间】:2017-02-09 17:10:10
【问题描述】:
考虑这个简单的模板特化:
template<typename T, size_t I>
struct S {};
template<typename T>
struct S<T, std::tuple_size<T>::value> {};
GCC 不编译它,因为它在模板参数std::tuple_size<T>::value 中使用模板参数T:
错误:模板参数 'std::tuple_size<_tp>::value' 涉及模板参数
现在让我们在tuple_size 模板参数中将T 替换为typename std::remove_reference<T>::type:
// 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 标志的 MSVS 编译第二个示例,它会因错误 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 Community 2015 Update 3 及其默认编译器和 GCC 6.2.1。
试过 Clang 3.8.0。它不会编译两个 sn-ps,并出现类似于 GCC 消息的错误:
错误:非类型模板参数依赖于模板参数 偏特化
【问题讨论】:
标签: c++ gcc visual-c++ language-lawyer template-specialization