考虑以下 code :
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>'
这是asked关于之前,但那里没有答案。另一方面,如果
B
不是模板,我写这个code :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<X>
它是一个不完整的类型。并且类成员访问运算符需要一个完整的类型。
但是您可以使用以下代码解决这种情况:
#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() {}
关于c++ - 约束成员模板的外定义规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63642952/