SFINAE表达式无法使用clang进行编译

时间:2016-06-01 21:13:49

标签: gcc clang c++14 sfinae enable-if

这看起来像是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在任何一种情况下都能正常工作。

1 个答案:

答案 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?