请考虑以下代码:
template <typename T>
struct S
{
template <typename = void>
static constexpr bool B = true;
template <std::enable_if_t<S<T>::template B<>, int> = 0>
void f();
};
template <typename T>
template <std::enable_if_t<S<T>::template B<>, int>>
void S<T>::f() {}
gcc接受了这一点,但clang拒绝了它:
error: out-of-line definition of 'f' does not match any declaration in 'S<T>'
这个以前也有人问过,但那里没有答案。
另一方面,如果b
不是模板,并且我编写了以下代码:
template <typename T>
struct S
{
static constexpr bool B = true;
template <std::enable_if_t<S<T>::B, int> = 0>
void f();
};
template <typename T>
template <std::enable_if_t<S<T>::B, int>>
void S<T>::f() {}
clang接受这一点,但gcc拒绝使用以下代码:
error: no declaration matches 'void S<T>::f()'
那么这些片段中的任何一个是否有效呢?
在s
的定义过程中,它是一个不完整的类型。并且类成员访问运算符需要完整的类型。
但您可以使用以下代码解决此问题:
#include <type_traits>
template <typename T>
struct S {
template <typename = void>
static constexpr bool B = true;
template <
typename TX = T,
std::enable_if_t<S<TX>::template B<>, int> = 0>
void f();
};
template <typename T>
template <typename TX, std::enable_if_t<S<TX>::template B<>, int>>
void S<T>::f() {}
//-----------
template <typename T>
struct S2 {
static constexpr bool B = true;
template <
typename TX = T,
std::enable_if_t<S2<TX>::B, int> = 0>
void f();
};
template <typename T>
template <typename TX, std::enable_if_t<S2<TX>::B, int>>
void S2<T>::f() {}