c++ - 检查成员函数是否存在且未被 SFINAE 继承

标签 c++ templates c++14 sfinae

如何检查成员函数是否存在并且继承?

我需要它来解决以下示例的歧义:

类型可以具有 foo()bar() 成员函数。 调用者调用给定类型存在的调用者。但是,DerivedWithBar 继承了 BaseWithFoofoo(),但定义了自己的 bar()。因此,Caller 不知道要调用哪个函数。

我需要一种方法来使非继承的 foo 优先于继承的 bar(),但我不知道如何检查成员函数是否是否遗传。

#include <iostream>

struct BaseWithFoo
{
    template <typename T> void foo(T&&){std::cout << "Base::foo" << std::endl;}
};

struct DerivedWithBar : public BaseWithFoo
{
    template <typename T> void bar(T&&){std::cout << "DerivedWithBar::bar" << std::endl;}
};

struct DerivedWithFoo : public BaseWithFoo
{
    template <typename T> void foo(T&&){std::cout << "DerivedWithFoo::foo" << std::endl;}
};

struct EmptyDerived : public BaseWithFoo {};

struct BaseWithBar
{
    template <typename T> void bar(T&&){std::cout << "BaseWithBar::bar" << std::endl;}
};


struct Caller
{
    template <typename T>
    auto call(T&& x) -> decltype(x.foo(*this), void())
    {
        x.foo(*this);
    }

    template <typename T>
    auto call(T&& x) -> decltype(x.bar(*this), void())
    {
        x.bar(*this);
    }
};

int main()
{
  Caller c;
  c.call(BaseWithFoo());
  c.call(DerivedWithFoo());
  c.call(DerivedWithBar());
  c.call(EmptyDerived());
  c.call(BaseWithBar());
}

live example

所需输出:

Base::foo
DerivedWithFoo::foo
DerivedWithBar::bar
Base::foo
BaseWithBar::bar

最佳答案

我找到了一种通过比较成员函数指针的类型来区分继承和非继承成员函数的方法。

以下是我的完整问题的部分解决方案(“使非继承的成员函数优先于继承的成员函数”)。这只会调用非继承的 foo 或非继承的 bar

struct Caller
{    
    template <typename T>
    auto call(T&& x) -> decltype(x.foo(*this),
        std::enable_if_t<
            std::is_same<
                decltype(&T::template foo<decltype(*this)>),
                void (T::*)(decltype(*this))
            >::value
        >())
    {
        x.foo(*this);
    }

    template <typename T>
    auto call(T&& x) -> decltype(x.bar(*this),
        std::enable_if_t<
            std::is_same<
                decltype(&T::template bar<decltype(*this)>),
                void (T::*)(decltype(*this))
            >::value
        >())
    {
        x.bar(*this);
    }
};

live example

关于c++ - 检查成员函数是否存在且未被 SFINAE 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38345842/

相关文章:

c++ - 警告 : Could not find codec parameters (. ./../modules/highgui/src/cap_ffmpeg_impl.hpp:540)

c++ - Qt 应用程序图标不起作用

c++ - 2 个在命名空间内具有相同名称的类

html - 在模板中访问 vue 环境变量

c++ - 这种继承有什么问题?

c++ - 函数模板重载 : const* vs. const&

c++ - 为什么 Multimap 不将一个索引处的所有值写入文本文件?

c++ - OpenCV ARDrone 编译问题

boost - Boost.Hana 中的 BOOST_FUSION_ADAPT_ASSOC 相当于什么?

c++ - 在转换参数上使用 std::forward