c++ - 为什么 SFINAE 不能跨多重继承工作?

标签 c++ templates sfinae

代码如下:

#include <utility>
#include <type_traits>

template <class T>
class ClassWithDisabledFoo
{
public:
    template <class U = T, std::enable_if_t<std::is_integral<U>::value, int> = 0>
    void foo(){}
};

class ClassWithFoo
{
public:
    void foo(){}
};

class Derived: public ClassWithFoo, public ClassWithDisabledFoo<double>
{

};

void test()
{
    Derived d;
    d.foo();
}


在调用d.foo()时,clang和gcc都表示对foo的调用是不明确的,尽管ClassWithDisabledFoo::fooenable_if 禁用。如果我将 foo 定义从 ClassWithFoo 移动到 Derived,代码就会编译。

为什么这不起作用?我怎样才能使它起作用?

最佳答案

您的示例中没有发生重载解析,因此 SFINAE 并不重要。

这里的关键是名称查找发生在重载解析之前。名称查找找到重载集,然后对找到的集执行重载解析。

名称必须映射到单个对象类型内的单个集合。在您的情况下,相同的名称映射到两个不同子对象的成员,因此名称查找不明确。立即的解决方案是添加 using 声明:

class Derived: public ClassWithFoo, public ClassWithDisabledFoo<double>
{
    using ClassWithFoo::foo;
    using ClassWithDisabledFoo::foo;
};

这会将名称引入到 Derived 中,现在可以明确地找到声明引用由我们引入的成员组成的重载集。

关于c++ - 为什么 SFINAE 不能跨多重继承工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59178136/

相关文章:

c++ - 使用模板模板参数专门化基类

javascript - 对所有页面使用相同的 Handlebars 模板

C++ 可变参数模板数组/访问元素

c++ - 请帮助我理解为什么 SFINAE 在这种情况下不起作用

C++模板如果匹配类型则调用成员函数否则抛出异常?

c++ - 使用SFINAE计算不同元素的大小

c++ - 使用 `std::shared_ptr` 时有效地节省内存/编程

C++ 和 CTime & 系统时钟更改

c++ - 当在 C++ 运行时确定精确形状时,如何将二维数组传递给外部函数?

c++ - 带有 pimpl 习语的模板化类不正确