这看起来像是clang中的一个问题(我已经打开了一个错误here),但我想确定我没有犯错。
请考虑以下代码:
#include <type_traits>
#include <cstddef>
template<std::size_t N, std::size_t M, std::enable_if_t<not (N>M)>* = nullptr> // (1)
struct S: public S<N+1, M> { };
template<std::size_t N>
struct S<N, N> { };
int main() {
S<0, 1> c{};
}
无法使用以下错误进行编译:
8:错误:非类型模板参数专门化具有依赖类型的模板参数&#; std :: enable_if_t M)&gt; *&#39; (又名&#39; typename enable_if M),void&gt; :: type *&#39;)
struct S {};
使用以下行而不是(1):
,相同的代码按预期工作template<std::size_t N, std::size_t M, typename = std::enable_if_t<not (N>M)>>
SFINAE表达几乎相同。它基于std::enable_if_t
的专业化,我希望两个例子都有相同的结果(成功或失败)。
我的期望是错的吗?
请注意,GCC在任何一种情况下都能正常工作。
答案 0 :(得分:2)
我认为这实际上是一个gcc bug,因为[temp.class.spec]:
与专门化相对应的模板参数的类型 非类型参数不应该依赖于参数 专业化。 [示例:
template <class T, T t> struct C {}; template <class T> struct C<T, 1>; // error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; template< int X > class A<X,&array> { }; // error
- 示例]
在您的示例中,第3个模板参数的类型取决于参数。将其交换为typename = std::enable_if_t<...>
时,此规则不再适用。
注意:有没有理由在这里使用SFINAE,而不是static_assert
- ing?