c++ - 继承构造函数在 C++ 中有多大用处?

标签 c++ inheritance constructor c++11 perfect-forwarding

当我参加 C++ 标准委员会 session 时,他们正在讨论放弃 Inheriting Constructors 的利弊。因为还没有编译器供应商实现它(感觉用户并没有要求它)。

让我快速提醒大家什么是继承构造函数:

struct B
{
   B(int);
};

struct D : B
{
  using B::B;
};

一些供应商建议使用右值引用和可变参数模板(完美的转发构造函数),在继承类中提供转发构造函数来避免继承构造函数是微不足道的。

例如:

struct D : B
{
  template<class ... Args> 
    D(Args&& ... args) : B(args...) { } 
};

我有两个问题:

1) 您能否根据您的编程经验提供真实世界(非人为)的示例,这些示例将从继承构造函数中受益匪浅?

2) 您能想到哪些技术原因会阻止“完美的转发构造函数”成为合适的替代方案?

谢谢!

最佳答案

2) Are there any technical reasons you can think of that would preclude "perfect forwarding constructors" from being an adequate alternative?

我在这里展示了完美转发方法的一个问题:Forwarding all constructors in C++0x .

此外,完美的转发方法不能“转发”基类构造函数的显式性:要么它始终是转换构造函数,要么永远不会,并且基类将始终直接初始化(始终使用所有构造函数,甚至是明确的)。

另一个问题是初始化列表构造函数,因为你无法推断 Argsinitializer_list<U> .相反,您需要使用 B{args...} 转发到基地。 (注意大括号)并初始化 D带有 (a, b, c) 的对象或 {1, 2, 3}= {1, 2, 3} .在这种情况下,Args将是初始化列表的元素类型,并将它们转发给基类。然后初始化列表构造函数可以接收它们。这似乎会导致不必要的代码膨胀,因为模板参数包可能会为每种不同的类型和长度组合包含大量类型序列,并且因为您必须选择初始化语法,这意味着:

struct MyList {
  // initializes by initializer list
  MyList(std::initializer_list<Data> list);

  // initializes with size copies of def
  MyList(std::size_t size, Data def = Data());
};

MyList m{3, 1}; // data: [3, 1]
MyList m(3, 1); // data: [1, 1, 1]

// either you use { args ... } and support initializer lists or
// you use (args...) and won't
struct MyDerivedList : MyList {
  template<class ... Args> 
  MyDerivedList(Args&& ... args) : MyList{ args... } { } 
};

MyDerivedList m{3, 1}; // data: [3, 1]
MyDerivedList m(3, 1); // data: [3, 1] (!!)

关于c++ - 继承构造函数在 C++ 中有多大用处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4129023/

相关文章:

c++ - 如何在 C++ 中使用 override 关键字进行多重泛型继承?

Swift 中的继承和扩展

c++ - "specialize"一个基对象变成派生对象?

c++ - 完美转发STL容器到模板类

c# - 静态工厂方法与公共(public)构造函数

c++ - 看起来实际上是无限的 'for' 循环

c++ - 隐式转换为 C++ 模板对象

Java,使用参数列表进行构造函数调用?

c++ - 非静态成员函数的无效使用(在 qt 中)

c++ - 使用表达式模板时,根据左值/右值提供类的不同实现