例如
#include <array>
class Range
{
public:
Range(std::array<float, 2> ends) : m_ends(ends) {}
private:
std::array<float, 2> m_ends;
};
我可以
Range r({1, 2});
现在我有另一个类(class)
class Box
{
public:
Box(std::array<Range, 3> ranges) : m_ranges(ranges) {}
private:
std::array<Range, 3> m_ranges;
};
我希望我能做到以下几点
Box b({{1,2}, {3,4}, {5,6}});
但我不能。我怎样才能更改代码以使其成为可能。
最佳答案
std::array
有点奇怪。它没有用户定义的构造函数,因此它很像普通结构。所以std::array<float,2>
很像
struct two_floats {
float array[2];
};
正因为如此,如果你初始化一个,你会合乎逻辑地这样做:
two_floats x = {{1,2}};
std::array<float,2> y = {{1,2}};
外括号用于结构本身,内括号用于结构的内容。
碰巧只提供一组大括号就可以了:
two_floats x = {1,2};
但这是由于 C++ 中的一个特殊规则,允许在某些情况下省略大括号。类似于如何仅使用一组大括号初始化二维数组:
float x[2][2] = {1,2,3,4};
这就是当你像这样初始化你的范围时发生的事情:
Range r({1, 2});
相当于
std::array<float,2> arg = {1,2}; // one set of braces omittted
Range r(arg);
但更明确地写为:
std::array<float,2> arg = {{1,2}};
Range r(arg);
初始化 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);
所以如果我们替换初始值设定项,我们会得到:
Box b({{{{1,2}},{{3,4}},{{5,6}}}});
那行得通。但它很丑陋。这个初始化太复杂了,不允许在这里省略额外的大括号,这就是你遇到的问题。
解决此问题的一种方法是提供额外的构造函数,这些构造函数采用各个数组元素。
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;
};
现在您可以像最初想要的那样初始化您的 Box:
Box b({{1,2}, {3,4}, {5,6}});
关于c++ - 如何实现方便的初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37747134/