我正在寻找清晰的语法糖来从显式值初始化boost::multi_array
。
double g[5][5] = {
{-0.0009 , 0.003799 , 0.00666 , 0.00374 , 0.00186 },
{-0.0008 , 0.0176 , 0.0619 , 0.0159 , 0.00324 },
{0.00099 , 0.0475 , 0.666 , 0.0376 , 0.00758 },
{0.00242 , 0.02189 , 0.0624 , 0.0192 , 0.0008 },
{0.00182 , 0.00404 , 0.00479 , 0.00924 , 0.00189 }};
boost::multi_array_ref<double,2> mg((double*)g,boost::extents[5][5]);
字符串
我不喜欢这样,因为它需要2个变量而不是1个,三倍冗余的[5][5]
尺寸(大小可以通过嵌套的花括号列表推断),以及从double[][]
到double*
的转换。
我确实喜欢这样一个事实,即没有从g
到mg
的复制,而且g
的初始化方式令人赏心悦目(即嵌套的、结构化的初始化列表,具有最少的多余字符)。
1条答案
按热度按时间zpjtge221#
有几个可用的选项。所有这些都需要一些模板魔法;它们在语法表达和效率上有所不同。如果
boost::multi_array
和朋友们实际上提供了一些更有用的构造函数,生活会更容易,但遗憾的是,截至本文撰写时,情况并非如此。1)使用扁平
initializer_list
这个基本选项消除了一些冗余,并使语法糖相当好。它使用一个helper函数,该函数接受
initializer_list<t>
,将其转储到std::vector
中,并使用该函数首先创建const_multi_array_ref
,然后将其深度复制到multi-array
中。字符串
在这个版本中,
initializer_list
的适当大小只在运行时检查,但我认为在C++14中std::initializer_list::size()
将是constexpr
,这应该允许您使用static_assert
。2)从C数组初始化
这一个更接近于你的原始数组,但是你需要单独定义数组-我不认为你可以直接将它作为一个函数参数提供给一个冗余的类型转换。优点是因为你首先构建了一个标准的C数组,你可以在你的
multi_array_ref
中重用它,而不需要复制。与第一个选项相比,你需要一些额外的构造:CArray
用于从模板参数构造C数组类型。型
3)使用嵌套
initializer_list
s除了上面的代码,我们还需要一种方法来构造嵌套的
initializer_list
s,并将它们复制到一个数组中。型
最后一个来自this article的一点灵感。
fillArray()
例程是递归的,因此效率较低(我预计编译器也无法优化它)。