当我参加 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 .
此外,完美的转发方法不能“转发”基类构造函数的显式性:要么它始终是转换构造函数,要么永远不会,并且基类将始终直接初始化(始终使用所有构造函数,甚至是明确的)。
另一个问题是初始化列表构造函数,因为你无法推断 Args
至initializer_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/