c++ - 如何让基方法只在派生类没有定义同名方法的情况下定义

标签 c++

我有一个模板化基类,它定义了某种默认 功能,如果需要,模板化派生类可以重载这些功能。此“默认”功能作为采用任何参数的可变参数模板函数实现。

如果用户未能正确定义派生类的原型(prototype),则将无意中调用基类方法。

相反,如果派生类的编写者希望为现有函数实现新的原型(prototype),那么基类对于该函数名称将变得过时(它不会为其他选择不选择的派生方法提供通用的“回退”定义钩子(Hook)的这个特定原型(prototype))。

所以...我不想长篇大论,而是举例说明我正在尝试做的事情:

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 语句没有任何意义,但它们说明了我希望拥有的功能。这可以实现吗?

最佳答案

首先,您必须定义一些特征。特别是像这样测试成员函数是否存在的函数:

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)) {};

此特征使用表达式 SFINAE 来检测成员的存在,您可以阅读有关表达式 SFINAE 的更多信息 here .

定义此特征后,其用法变得简单,您可以定义其他类似的特征。所以在你的情况下,enable_if 会是这样的:

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

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

关于c++ - 如何让基方法只在派生类没有定义同名方法的情况下定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25070101/

相关文章:

c++使用多重继承调用基类的虚拟运算符==

c++ - 生成数独谜题所需的时间

c++ - 为可移动对象存储 'validness' 状态是一个好习惯吗?

c++ - 结构内部的 union ——如何做指定的初始值设定项?

c++ - 找到填充矩形的最少 MS Paint 操作数

C++11 "correct"延迟执行方式

C++ - 在覆盖期间调用析构函数时的类成员

c++ - C++ 函数的 VB6 声明给出 "Bad DLL calling convention"

c++ - Qt Sqlite 仅从脚本创建一张表

c++ - 暂住地址