c++ - std::array 构造函数继承

标签 c++ c++11

我正在尝试为数学 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};

[Live example]

关于c++ - std::array 构造函数继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24280521/

相关文章:

C++派生类是否可以继承基类的静态数据成员和静态成员函数?

C++ this怎么不是成员函数指针?

c++ - 为什么在按值返回列表初始化对象时不调用复制构造函数?

c++ - 我应该如何在工厂类中存储弱指针列表?

c++ - 当我将一组命令移到一个单独的函数中时出现代码段错误

c++ - 内存映射和排序文件后字节下落不明

c++ - 使两种类型的相同模板兼容

c++ - 在 C++11 中,可以在同一行声明全局变量和函数原型(prototype)吗?

c++ - 前向声明类模板的成员枚举

c++ - C++中的堆栈和堆内存