本文介绍了约束成员模板的外定义规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
考虑以下代码:
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 拒绝了:
gcc accepts this, but clang rejects it with:
error: out-of-line definition of 'f' does not match any declaration in 'S<T>'
这是询问 之前,但那里没有答案.
This has been asked about before, but there is no answer there.
另一方面,如果 B
不是模板,我写这个 代码:
On the other hand, if B
is not a template, and I write this 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 拒绝代码:
clang accepts this, but gcc rejects the code with:
error: no declaration matches 'void S<T>::f()'
那么这些片段中的任何一个都有效吗?
So are either of these snippets valid?
推荐答案
在 S
的定义中,它是一个不完整的类型.并且类成员访问运算符需要一个完整的类型.
During the definition of S<X>
it is an incomplete type. And the class member access operator requires a complete type.
但是你可以用下面的代码解决这个问题:
But you could solve the situation with the following code:
#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() {}
这篇关于约束成员模板的外定义规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!