通过可变参数模板进行C++11构造函数继承

C++11 constructor inheritance through variadic templates

本文关键字:C++11 构造函数 继承 变参 参数      更新时间:2023-10-16

我最近遇到了一个实例,其中我意识到我编写的几个类共享了很多功能。 我意识到我可以使用一些模板参数将这些类概括为一个公共基础。 问题是这些类有大约 20 个不同的重载构造函数,其中大多数类功能都是实现的。 使用我想出了这里说明的解决方案:

template <typename T>
class Base {
  protected:
    T member_;
  public:
    Base(int a) { /* ... */ }
    Base(double a) { /* ... */ }
    Base(char a) { /* ... */ }
    Base(int a, double b, char c) { /* ... */ }
    // etc...
};
class Derived1 : public Base<int> {
  public:
    template <typename... Args>
    Derived1(Args... args) : Base(args...) { }
    // other constructors specific to Derived1
};
class Derived2 : public Base<char> {
  public:
    template <typename... Args>
    Derived2(Args... args) : Base(args...) { }
    // other constructors specific to Derived2
};

我在这里有几个问题:

  1. 是否有与此相关的运行时性能影响? (环顾四周后,似乎我应该在派生类中使用右值引用和std::forward,对吧?
  2. 从代码可维护性的角度来看,这是一个好主意吗?
  3. 这种方法有哪些缺陷? (例如,其他地方的类似示例似乎使用了explicit关键字。 为什么?
  4. 有没有更好、更标准、更安全或更易读的方法?

在 C++11 中,构造函数可以继承。

请参阅 https://stackoverflow.com/a/434784/232574

  1. 是的,您应该使用完美的转发。如果构造函数以内联方式声明,则对性能的影响为零。

  2. 这是一个"看起来很吓人的模板",但很容易被对模板一无所知的人识别。取决于你的维护者,我猜?

  3. 您需要注意拦截用于派生类的复制和移动构造函数的调用,因为可变参数完美转发签名匹配所有内容。正确约束enable_if通常需要比转发构造函数本身更多的代码。

  4. 继承构造函数是执行此操作的"更好"方法。指定该功能是为了避免捕获应转到派生类构造函数的签名。编译器支持可能是不确定的:它不是最容易实现的功能,也不是最需要的功能,因此实现者将其推迟了相当长的一段时间。