【发布时间】:2014-10-19 01:42:11
【问题描述】:
下面Foo的特化永远不会被使用; Clang 会发出警告,而 GCC 不会。
template <typename>
struct Foo { static const int value = 0; };
template <template <typename...> class C, typename ...Ts>
struct Foo<C<Ts..., int>> { static const int value = 1; };
为什么这不会导致错误?
以下代码演示了这一点:
template <typename...>
struct Bar {};
static_assert(!Foo<Bar<char,double,int>>::value,"");
【问题讨论】:
-
@MarkB 部分特化匹配依赖于模板参数推导,这里的包不会被推导(不是模板参数列表中最后一个模板参数的包扩展是非推导上下文) .
-
我猜这是因为确定是否可以使用部分专业化通常是不可行的。但我无法证明。
-
@kerrekSB 不,这就是问题所在。我认为 OP 知道专业化是“无法访问的”,OP 会问为什么拥有无法访问的专业化并不是错误。
-
第 14 条将许多结构标记为格式错误但不需要诊断,这很大程度上是因为诊断它们是不可行的;令人惊讶的是,永远不会使用的部分专业化不是其中之一......
-
@T.C.完整的 sn-p:
template<class T> struct foo { template<class Unused=void> typename std::enable_if< !std::is_same<int, T>::value >::type not_an_int() const { std::cout << "not an int\n"; } };这在 C++ 下是非法的,因为根据我对标准的阅读,foo<int>::not_an_int<?>()没有有效的专业化。现在我看到了他们这样做的原因为什么(为了在将来允许更多、更智能的template函数检查,以便在实例化之前捕获更多无效代码),但它也确实妨碍了。
标签: c++ c++11 variadic-templates template-specialization