当我参加C++标准委员会会议时,他们正在讨论删除继承构造函数的优缺点,因为还没有编译器供应商实现它(用户没有要求它的意义).
让我快速提醒大家继承构造函数是什么:
struct B
{
B(int);
};
struct D : B
{
using B::B;
};
Run Code Online (Sandbox Code Playgroud)
一些供应商提出使用r值引用和可变参数模板(完美转发构造函数),在继承类中提供可以避免继承构造函数的转发构造函数是微不足道的.
例如:
struct D : B
{
template<class ... Args>
D(Args&& ... args) : B(args...) { }
};
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
1)您能否从编程经验中提供真实世界(非人为的)示例,这些示例将从继承构造函数中获益匪浅?
2)您是否有任何技术原因可以将"完美的转发建设者"排除在适当的替代方案之外?
谢谢!
我在我的项目中遇到以下错误:
error: use of deleted function ‘C::C(int)’ note: ‘C::C(int)’ is implicitly deleted because the default definition would be ill-formed: error: use of deleted function ‘M::M()’
这是我正在使用的代码:
struct M {
M(int){}
M() = delete; // Allowing this would work.
};
struct B {
B(int) {}
B() = delete;
};
struct C : public B {
using B::B;
M n = {5};
// C(int i) : B(i) {} // Adding this would work
};
C c{1};
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会这样?
很明显,语言愿意在继承的构造函数的末尾添加更多的初始化(因为它愿意调用默认的构造函数).显然,它愿意隐式地将对非默认构造函数(类初始化)的调用添加到显式定义的构造函数的末尾.但由于某种原因,我不明白,它不愿意同时做这两件事.
根据这个问题,完美转发不够完美,不应该在这里使用.
注意:在实际情况下,构造函数 …
假设我有一个类,我打算将它作为可实例化的类直接暴露给程序员:
class Base
{
public:
Base(std::string text) : m_text(std::move(text)) {}
private:
std::string m_text;
};
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.这里不需要rvalue构造函数.现在,在未来的某个时刻,我决定扩展Base:
class Derived : public Base
{
public:
Derived(const std::string &text) : Base(text) {}
};
Run Code Online (Sandbox Code Playgroud)
这让我感到困惑:我无法在Derived中按值获取字符串,因为这就是Base已经在做的事情 - 我最终会得到2个副本和1个移动.这里的const-reference构造函数还对rvalues执行不必要的复制.
问题是:如何复制+仅移动一次(就像Base中的简单构造函数一样)而不添加更多构造函数?