Fai*_*ali 31 c++ inheritance constructor perfect-forwarding c++11
当我参加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)您是否有任何技术原因可以将"完美的转发建设者"排除在适当的替代方案之外?
谢谢!
Joh*_*itb 21
2)您是否有任何技术原因可以将"完美的转发建设者"排除在适当的替代方案之外?
我在这里展示了一个完美转发方法的问题:在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] (!!)
Run Code Online (Sandbox Code Playgroud)