当 base 是模板类型时使用 base class 实现

Use base class implementation when base is template type

我有一个 class 接收其基类型作为模板 arg,我希望我的派生 class 调用函数 print。默认情况下,此函数应使用派生实现,但如果基础 class 具有打印功能,则应使用基础实现。

#include <iostream>

class BaseWithPrint {
  public:
    static void print(int i) { std::cout << "Base::print\n"; }
};

class BaseWithoutPrint {
};

template <typename B>
class Derived : public B {
  public:
    static void print(bool b) { std::cout << "Derived::bool_print\n"; }

    template <typename T>
    static void print(T t) { std::cout << "Derived::print\n"; }
    
    void Foo() {
        print(1);
        print(true);
        print("foo");
    }
};

int main()
{
    Derived<BaseWithPrint> d1;
    d1.Foo();
    
    
    Derived<BaseWithoutPrint> d2;
    d2.Foo();

    return 0;
}

此代码仅调用 print 的派生版本。

代码可见

https://onlinegdb.com/N2IKgp0FY

如果你知道基础class会有某种print,那么你可以将 using B::print 添加到派生的 class。如果在派生中没有找到完美匹配,那么它将检查基数。

Demo

要处理 可能 是基础 print 的情况,我认为你需要求助于SFINAE。最好的 SFINAE 方法实际上取决于您的真实情况。以下是我如何解决您的示例问题:

template <class T, class = void>
struct if_no_print_add_an_unusable_one : T {
    // only ever called if derived calls with no args and neither
    // the derived class nor the parent classes had that print.
    // ie. Maybe best to force a compile fail:
    void print(); 
};

template <class T>
struct if_no_print_add_an_unusable_one <T, decltype(T().print(int()))> : T {};

//====================================================================


template <class B>
class Derived : public if_no_print_add_an_unusable_one<B> {

    using Parent = if_no_print_add_an_unusable_one<B>;
    using Parent::print;

public:

    // ... same as before
};

Demo