如何让一个基本方法定义只有当派生类没有定义一个同名的方法 [英] How to let a base method be defined only if the derived class does not define a method of the same name

查看:123
本文介绍了如何让一个基本方法定义只有当派生类没有定义一个同名的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板化的基类,它定义了某种模板派生类可以重载的默认功能。

I have a templated base class which defines some sort of default functionality which a templated derived class can overload if it wants to. This "default" functionality is implemented as variadic template functions taking any argument.

如果用户无法正确定义派生类的原型,那么基类方法将无意中成为称为。

If a user fails to properly define the derived class' prototype then the base class method will unintentionally be called.

相反,如果派生类的作者希望为现有函数实现一个新的原型,那么对于该函数名,Base类将会过时为其他派生方法提供通用的后备,选择不定义这个特定的钩子原型)。

Conversely, if the writer of the derived class wishes to implement a new prototype for an existing function then the Base class will become obsolete for that function name (it won't provide generic "fallback" for other derived methods that choose not to define this particular prototype of the hook).

所以...而不是ramble我会给我想要做的示例:

So... rather than ramble on I'll give an example of what I'm trying to do:

template <typename Derived>
class Base
{
    template <typename... Args>
    void hook1(const Args&...) // -> std::enable_if(Derived::hook1 doesn't exist)
    {
        // do nothing
    }

    template <typename... Args>
    void hook2(const Args&...) // -> std::enable_if(Derived::hook2 doesn't exist)
    {
        // do nothing
    }

    // ... hook3, hook4, etc.
};

// this particular derived class overloads only hook1
class DerivedExample : public Base<DerivedExample>
{
    template <typename SomeArg>
    void hook1(const SomeArg& arg)
    {
        // do something
    }
};

很明显,这些 enable_if 语句任何意义,但他们说明了我将像具有的功能。这是可以实现的吗?

Clearly, those enable_if statements don't make any sense, but they illustrate the functionality I would like to have. Is this achievable?

推荐答案

首先你必须定义一些特征。特别是测试成员函数的存在,如下所示:

First you're going to have to define some traits. In particular one that tests the presence of a member function like so:

struct has_hook_one_impl {
    template<typename T>
    static auto test(int) -> decltype(std::declval<T&>().hook1(0), std::true_type{});
    template<typename...>
    static std::false_type test(...);
};

template<typename T>
struct has_hook_one : public decltype(has_hook_one_impl::test<T>(0)) {};

此trait使用表达式SFINAE来检测成员的存在,可以阅读更多关于表达式SFINAE < a href =http://stackoverflow.com/questions/12654067/what-is-expression-sfinae>这里。

This trait uses expression SFINAE to detect the presence of the member, you can read more about expression SFINAE here.

这个特质定义它的用法变得简单,你可以定义其他类似的。所以在你的情况下, enable_if 将是这样:

After this trait is defined its usage becomes simple and you could define others that are similar to it. So in your case, the enable_if would be like this:

template <typename Derived>
class Base
{
    template <typename... Args>
    auto hook1(const Args&...) -> typename std::enable_if<!has_hook_one<Derived>::value>::type
    {
        // do nothing
    }
};

实现检测其他成员函数存在的其他元函数应该足够容易扩展,被作为练习留给读者。

Implementing the other meta function that detects the presence of the other member functions should be easy enough to extend and was left out as an exercise to the reader.

这篇关于如何让一个基本方法定义只有当派生类没有定义一个同名的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆