如何实现方便的初始化?

Tia*_*iao 6 c++ initialization c++11

例如

#include <array>

class Range
{
public:
    Range(std::array<float, 2> ends) : m_ends(ends) {}

private:
    std::array<float, 2> m_ends;    
};
Run Code Online (Sandbox Code Playgroud)

我可以

Range r({1, 2});
Run Code Online (Sandbox Code Playgroud)

现在我有另一堂课

class Box
{
public:
    Box(std::array<Range, 3> ranges) : m_ranges(ranges) {}

private:
    std::array<Range, 3> m_ranges;    
};
Run Code Online (Sandbox Code Playgroud)

我希望我能做到以下几点

Box b({{1,2}, {3,4}, {5,6}});
Run Code Online (Sandbox Code Playgroud)

但是我不能.如何更改代码以使其成为可能.

Vau*_*ato 4

std::array有点奇怪。它没有用户定义的构造函数,因此它很像普通结构。所以std::array<float,2>很像

struct two_floats {
   float array[2];
};
Run Code Online (Sandbox Code Playgroud)

因此,如果你初始化一个,你在逻辑上会这样做:

two_floats          x = {{1,2}};
std::array<float,2> y = {{1,2}};
Run Code Online (Sandbox Code Playgroud)

外部大括号用于结构本身,内部大括号用于结构的内容。

它恰好只提供一组大括号:

two_floats x = {1,2};
Run Code Online (Sandbox Code Playgroud)

但这是由于 C++ 中的特殊规则允许在某些情况下省略大括号。与仅使用一组大括号初始化二维数组的方式类似:

float x[2][2] = {1,2,3,4};
Run Code Online (Sandbox Code Playgroud)

这就是当你像这样初始化你的范围时发生的事情:

Range r({1, 2});
Run Code Online (Sandbox Code Playgroud)

这相当于

std::array<float,2> arg = {1,2}; // one set of braces omittted
Range r(arg);
Run Code Online (Sandbox Code Playgroud)

但更明确地写为:

std::array<float,2> arg = {{1,2}};
Range r(arg);
Run Code Online (Sandbox Code Playgroud)

初始化 Box 时也会发生类似的情况。如果我们明确地写出初始化,它将如下所示:

std::array<float,2> box_arg1 = {{1,2}};
std::array<float,2> box_arg2 = {{3,4}};
std::array<float,2> box_arg3 = {{5,6}};
std::array<Range,3> box_args = {{box_arg1,box_arg2,box_arg3}};
Box b(box_args);
Run Code Online (Sandbox Code Playgroud)

因此,如果我们替换初始化器,我们会得到:

Box b({{{{1,2}},{{3,4}},{{5,6}}}});
Run Code Online (Sandbox Code Playgroud)

那行得通。但它非常丑陋。这个初始化太复杂,不允许在这里省略额外的大括号,这就是您遇到的问题。

解决此问题的一种方法是提供采用各个数组元素的附加构造函数。

class Range
{
public:
    Range(float x,float y) : m_ends{x,y} { }
    Range(std::array<float, 2> ends) : m_ends(ends) {}

private:
    std::array<float, 2> m_ends;
};

class Box
{
public:
    Box(Range x,Range y,Range z) : m_ranges{x,y,z} {}
    Box(std::array<Range, 3> ranges) : m_ranges(ranges) {}

private:
    std::array<Range, 3> m_ranges;
};
Run Code Online (Sandbox Code Playgroud)

现在您可以像您最初想要的那样初始化您的 Box:

Box b({{1,2}, {3,4}, {5,6}});
Run Code Online (Sandbox Code Playgroud)