c++ - 是否可以检查是否为类定义了成员函数,即使成员是从未知基类继承的

标签 c++ sfinae

我发现类似的问题和答案,如 this one .但是,正如我所尝试的那样,只有在被测试的成员直接定义在被测试的类中时,这个 SFINAE 测试才会成功。例如下面的类 BD1 打印 HAS 而其他两个打印 NOT HAS。有没有办法判断一个类是否有成员,是自己定义的,还是基类定义的,这种情况下不知道基类的名字。动机是我想编写一个通用函数,如果它存在,它将调用某个方法(无论是否来自基类,参数的类型都是通用的,保留其可能基类的类型)。

#include <iostream>

class HasFoo
{
    public :

    typedef char Small;
    typedef struct {char; char;} Large;

    template <typename C, void (C::*) ()> class SFINAE {};

    template <typename C> static Small test (SFINAE<C, &C::foo> *)
    {
        std::cout << "HAS" << std::endl;
    }

    template <typename C> static Large test (...)
    {
        std::cout << "NOT HAS" << std::endl;
    }
};

class B
{
    public :

    void foo () {}
};

class D1 : public B
{
    public :

    void foo () {} // overide
};

class D2 : public B
{
    public :

    using B::foo;
};

class D3 : public B {};

int main ()
{
    HasFoo::test<B>(0);
    HasFoo::test<D1>(0);
    HasFoo::test<D2>(0);
    HasFoo::test<D3>(0);
}

最佳答案

很遗憾,在 C++03 中这是不可能的,抱歉。

在 C++11 中,由于 decltype 的魔力,事情变得很多容易。 decltype 让您可以编写表达式来推断其结果的类型,因此您可以完美地命名基类的成员。如果方法是模板,则 SFINAE 应用于 decltype 表达式。

#include <iostream>

template <typename T>
auto has_foo(T& t) -> decltype(t.foo(), bool()) { return true; }

bool has_foo(...) { return false; }


struct Base {
    void foo() {}
};

struct Derived1: Base {
    void foo() {}
};

struct Derived2: Base {
    using Base::foo;
};

struct Derived3: Base {
};

int main() {
    Base b; Derived1 d1; Derived2 d2; Derived3 d3;

    std::cout << has_foo(b) << " "
              << has_foo(d1) << " "
              << has_foo(d2) << " "
              << has_foo(d3) << "\n";
}

不幸的是,ideone 的 gcc 版本太旧了,clang 3.0 也好不到哪儿去。

关于c++ - 是否可以检查是否为类定义了成员函数,即使成员是从未知基类继承的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11008189/

相关文章:

c++ - 如何申报 SFINAE 类(class)?

c++ - 检查类是否具有特定成员函数的其他方法

C++ 结构和构造函数

c++ - 编译时可配置回调

c++ - 如何将 mat 图像转换为字符串(array 2d<rgb pixel>)?

c++ - 如何断言应该使用 C++11 来编译我的程序?

c++ - 在再次读取 `std::cin` 之前如何清除它的内容?

c++ 03:由于enable_if,互斥方法

c++ - 使用不同的 enable_if 条件选择成员函数

c++ - 依赖非类型参数包 : what does the standard say?