如何在编译时在初始化列表中包含不同数量的对象?
How to include different number of objects at compile time in the initializer list?
我需要包含不同数量的对象,具体取决于所提供的 'define'
并且具有不同的 ctor 参数
inline static std::array<A::Output, NUM_OUTPUTS> s_Outputs =
{
#if NUM_OUTPUTS > 0
A::Output{0}
#endif
#if NUM_OUTPUTS > 1
, A::Output{1}
#endif
#if NUM_OUTPUTS > 2
, A::Output{2}
#endif
};
好吧,这取决于 NUM_OUTPUTS
应创建对象的相应数量。每个对象都有一个索引,第一个是'0
',每个下一个是'+1
'。
有没有更好的方法? 可能要在此类声明或其他任何内容中推出宏。
您可以定义各种模板并根据预处理器变量选择适当的专业化:
template<std::size_t I>
class outputs;
template<>
class outputs<1> {
static std::array<A::Output,1> value = {{0}};
};
template<>
class outputs<2> {
static std::array<A::Output,2> value = {{0}, {1}};
};
template<>
class outputs<3> {
static std::array<A::Output,3> value = {{0}, {1}, {2}};
};
inline static auto s_Outputs = outputs<NUM_OUTPUTS>::value;
对于更通用的变体,您可以将 std::index_sequence
与一个小辅助函数(C++17 代码)结合使用:
template<std::size_t... Ints>
decltype(auto) make_integer_array_helper(std::index_sequence<Ints...>) {
return std::array { A::Output{Ints...} };
}
template<std::size_t N>
decltype(auto) make_integer_array() {
return make_integer_array_helper(std::make_index_sequence<N>());
}
inline static auto s_Outputs = make_integer_array<NUM_OUTPUTS>();
使用std::make_index_sequence
and a variable template你可以做到。
#include <utility> // std::integer_sequence
template <std::size_t... I>
constexpr auto makeArray(std::index_sequence<I...>)
{
return std::array<A::Output, sizeof...(I)>{I...};
}
template<std::size_t NUM_OUTPUTS>
constexpr static std::array<A::Output, NUM_OUTPUTS> s_Outputs = makeArray(std::make_index_sequence<NUM_OUTPUTS>{});
现在你可以
constexpr auto arr1 = s_Outputs<1>; // 0
constexpr auto arr2 = s_Outputs<2>; // 0 1
constexpr auto arr3 = s_Outputs<3>; // 0 1 2
请注意,上述解决方案需要 c++14 编译器支持。
我需要包含不同数量的对象,具体取决于所提供的 'define' 并且具有不同的 ctor 参数
inline static std::array<A::Output, NUM_OUTPUTS> s_Outputs =
{
#if NUM_OUTPUTS > 0
A::Output{0}
#endif
#if NUM_OUTPUTS > 1
, A::Output{1}
#endif
#if NUM_OUTPUTS > 2
, A::Output{2}
#endif
};
好吧,这取决于 NUM_OUTPUTS
应创建对象的相应数量。每个对象都有一个索引,第一个是'0
',每个下一个是'+1
'。
有没有更好的方法? 可能要在此类声明或其他任何内容中推出宏。
您可以定义各种模板并根据预处理器变量选择适当的专业化:
template<std::size_t I>
class outputs;
template<>
class outputs<1> {
static std::array<A::Output,1> value = {{0}};
};
template<>
class outputs<2> {
static std::array<A::Output,2> value = {{0}, {1}};
};
template<>
class outputs<3> {
static std::array<A::Output,3> value = {{0}, {1}, {2}};
};
inline static auto s_Outputs = outputs<NUM_OUTPUTS>::value;
对于更通用的变体,您可以将 std::index_sequence
与一个小辅助函数(C++17 代码)结合使用:
template<std::size_t... Ints>
decltype(auto) make_integer_array_helper(std::index_sequence<Ints...>) {
return std::array { A::Output{Ints...} };
}
template<std::size_t N>
decltype(auto) make_integer_array() {
return make_integer_array_helper(std::make_index_sequence<N>());
}
inline static auto s_Outputs = make_integer_array<NUM_OUTPUTS>();
使用std::make_index_sequence
and a variable template你可以做到。
#include <utility> // std::integer_sequence
template <std::size_t... I>
constexpr auto makeArray(std::index_sequence<I...>)
{
return std::array<A::Output, sizeof...(I)>{I...};
}
template<std::size_t NUM_OUTPUTS>
constexpr static std::array<A::Output, NUM_OUTPUTS> s_Outputs = makeArray(std::make_index_sequence<NUM_OUTPUTS>{});
现在你可以
constexpr auto arr1 = s_Outputs<1>; // 0
constexpr auto arr2 = s_Outputs<2>; // 0 1
constexpr auto arr3 = s_Outputs<3>; // 0 1 2
请注意,上述解决方案需要 c++14 编译器支持。