文章https://www.fluentcpp.com/2018/05/15/make-sfinae-pretty-1-what-value-sfinae-brings-to-code/和 https://www.fluentcpp.com/2018/05/18/make-sfinae-pretty-2-hidden-beauty-sfinae/解释如何将 SFINAE 用于类方法。该类的第一个实现如下:
template<typename T>
class MyClass
{
public:
void f(T const& x);
void f(T&& x);
};
如果T
是一个引用,为了防止使用第二个函数f
,本文提出了以下解决方案:
template<typename T>
class MyClass
{
public:
void f(T const& x){}
template<typename T_ = T, typename = std::enable_if_t<!std::is_reference_v<T_>>>
void f(T&& x){}
};
将方法的返回类型替换为 std::enable_if
会不会更容易/更清晰?所以这个类看起来像下面这样:
template<typename T>
class MyClass
{
public:
void f(T const& x){}
std::enable_if_t<!std::is_reference_v<T>>> f(T&& x){}
};
最佳答案
首先,你的技术不行。 T
是 MyClass
中的固定类型enable_if_t<false>
是病式的。没有执行替换,所以这不是替换失败,它只是一个格式错误的签名。
你可以在某种程度上修复它
template<class T_=T>
std::enable_if_t<!std::is_reference_v<T_>>> f(T_&& x){}
现在,这种技术(使用返回值)在 (A) 构造函数和 (B) 您想要推导返回类型时不起作用。
它还将返回类型与 SFINAE 代码混合;两者没有任何关系。
最重要的是,这项技术和您正在复制的原始技术都与“所有模板必须具有有效的实例化”存在一些可疑的交互。我仍然不清楚这是否适用于固定模板类实例化的每个模板方法;如果是这样,那么你必须确保一些 T_
将使主体有效。
关于c++ - 类方法的 SFINAE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50648573/