我正在尝试为数学 vector 获取 std::array
的扩展变体(并在没有样板代码的情况下公开与 array
相同的接口(interface))。我知道 std::valarray
但我想要固定大小以便正确输入矩阵乘法。因此,我 array
非常适合。但是当我尝试继承构造函数时它失败了。
struct vec2d : std::array<float, 2>
{ using array::array; }; // simplified
struct vec : std::vector<float>
{ using vector::vector; };
std::array<float, 2> x = {1, 2};
vec y = {1, 2};
vec2d z = {1, 2}; // error: could not convert ‘{1, 2}’
// from ‘<brace-enclosed initializer list>’ to ‘vec2d’
此错误针对 GCC 4.8.2 和 clang 3.4 报告。最后说 vec2d
只有隐式默认/复制/移动构造函数。是的,array
仅具有隐式构造函数,而 vector
具有来自 initializer_list
的构造函数。但是由于 ctors 是继承的,因此很自然地继承了以与 array
初始化相同的方式初始化它的可能性。
问题:为什么我们有那个错误而不是预期的行为(类似于 array
初始化)?
注意:我可以手动编写转发以使其工作,但这看起来不像 ctor 继承那么优雅。
struct vec2d : std::array<float, 2>
{
using array::array;
// nasty boilerplate code I don't want to have in C++11
template <typename... Args>
vec2d(Args &&... args) : array({float(std::forward<Args>(args))...}) {}
};
最佳答案
std::array
被设计为聚合,因此它有意不定义任何构造函数。
不幸的是,这意味着不可能从它继承并获得相同的行为,因为聚合不能有基类。
为什么你需要继承std::array
呢?您打算添加任何私有(private)成员吗?如果没有,那么您可以围绕在 std::array
上运行的自由函数构建您的框架,或者可能是它的 typedef。
如果你真的想从 std::array
继承,你将不得不接受失去聚合状态并提供你自己想要的任何构造函数。
请注意,上面的答案仅适用于 C++11 和 C++14。在 C++17 中,聚合的定义被放宽以允许其中包含公共(public)基类,因此只需从 std::array
派生并删除 using
声明就足够了编译代码:
struct vec2d : std::array<float, 2>
{ }; // simplified
std::array<float, 2> x = {1, 2};
vec2d z = {1, 2};
关于c++ - std::array 构造函数继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24280521/