在 C++ 中,是否可以将 CRTP 与私有基一起使用?

In C++, is it possible to use CRTP with a private base?

在 C++ 中,我有许多 classes,与继承无关,它们定义了一个方法 std::string get_name() const

有许多 class 需要的实用函数是根据 get_name() 实现的。我希望实现 get_name() 的 classes 也能获得这些实用函数。举一个愚蠢的例子,假设对于每个 get_name 的 class,我想要 void print_name() const { std::cout << get_name() << std::endl; }。不过,有一些这样的功能,我不想在每个需要它们的 class 中重复它们。

听起来像是 CRTP 的工作:

template <class T>
class NameMethods {
public:

  void print_name() const {
     std::cout << static_cast<const T&>(*this).get_name() << std::endl;
  }

};

效果很好。

这里有问题 - 如果我希望 print_name() 在子 class 中是私有的怎么办?如果 subclass 从 NameMethods 私有继承,则向下转换将无法编译(不可访问的基)。我可以用 reinterpret_cast 替换它,一个简单的例子会起作用,但如果存在任何多重继承,reinterpret_cast 将不会做正确的事情,这在一般情况下可能存在。

有没有简单的方法来做这种事情?

谢谢!

编辑:我应该添加一点背景。我试图以一种尽可能使用协议的风格来编写,而不是抽象的 superclasses。如果我用 public get_name() 和受保护的 print_name() 创建一个抽象的 superclass,我可以很容易地让一切正常工作。问题是我不想要一个抽象的 superclass。它会有几个我想无关的子classes(因为我最终想使用mixins或MI组合它们)。

我的想法是,我将编写一个具体的 class,然后在那个 class 或超级 class 的某处,一些东西将实现 get_name()。具体 class 需要一组实用函数,但这些实用函数不应该是接口的一部分。

是的,你可以。 只要让你的 CRTP 基础 class 成为你 class 的朋友,沮丧就会再次起作用:

template <class T>
class NameMethods {
public:

  void print_name() const {
     std::cout << static_cast<const T&>(*this).get_name() << std::endl;
  }

};

class MyClass: private NameMethods<MyClass>
{
public:
    std::string get_name() const { return "MyClass";}
    void get_info() const
    {
        print_name();
    }
private:
    friend class NameMethods<MyClass>;
};

int main()
{
    MyClass c;
    c.get_info();

    return 0;
}

查看实例:https://godbolt.org/z/5oQvSq