我想写一些代码如下:
using int_list_t = std::initializer_list<int>;
struct ThreeDimensionalBox {
static constexpr int_list_t kDims = {1, 2, 3};
};
struct FourDimensionalBox {
static constexpr int_list_t kDims = {4, 5, 6, 7};
};
template<typename Box1, typename Box2>
struct CombinedBox {
static constexpr int_list_t kDims = Box1::kDims + Box2::kDims; // error
};
using SevenDimensionalBox = CombinedBox<ThreeDimensionalBox, FourDimensionalBox>;
是否有某种方法可以修复CombinedBox
的实现,以便SevenDimensionalBox::kDims
有效地绑定到{1, 2, 3, 4, 5, 6, 7}
?
我知道我可以用一个自定义的模板类替换std::initializer_list<int>
,这个模板类带有一个variadic int模板参数列表,通过标准的元编程递归技术可以有效地实现连接。我只是想知道是否存在只使用std::initializer_list
的解决方案。
2条答案
按热度按时间bz4sfanl1#
std::initializer_list
只能初始化为空、使用大括号括起的元素列表或通过复制。然而,即使使用复制构造,
std::initializer_list
引用的实际数组的生存期也是由原始std::initializer_list
对象的生存期决定的,原始std::initializer_list
对象是由一个用大括号括起来的元素列表初始化的。换句话说,复制std::initializer_list
并不复制数组或延长其生存期。因此,不可能将
std::initializer_list
连接起来。它们不应被用作容器。std::initializer_list
通常只应用作函数参数,作为一种轻量级的方式,将未指定大小的元素列表(用大括号括起来)传递给函数,以便函数进一步处理这些元素。您可能需要
std::array
来代替。类似于以下代码(需要C17,但不需要C20):ej83mcc02#
std::initializer_list
只有一个用途:作为一个初始化对象的工具,在一个花括号初始化列表({}
中的东西)被用于初始化该对象的范围内。关于这个类型的一切都是为此目的而构建的,并且它有一堆防火墙来防止你用它做其他任何事情。其中最重要的是
initializer_list
实际上并不存储任何东西;它 * 引用 * 存储在其他位置的值数组(也就是创建它的{}
的引用)。由于它不存储数组,并且它们只能从{}
语法结构构建,因此您不能给予它们一个数组来引用。它们只能通过复制从现有的initializer_list
对象中获取数组。并且只能从{}
或现有的initializer_list
中获得一个,而现有的initializer_list
只能从......嗯,您明白了。如果你需要进行编译时数组操作,
std::array
是一个更好的工具。如果你想连接两个花括号初始化列表,并使用结果初始化某个对象...你不能这样做。不要尝试将
initializer_list
用作快速和脏的数组类型。只在初始化对象时使用它。