我正在补充一个类似 python 的范围类(我们称之为
Range
)。
如果参数是 constexpr,我想使用 std::array
来存储数据,否则使用 std::vector
。
我想知道是否可以使用相同的界面来做到这一点,即,
Range range_1(10);
将数据存储在 std::array
中,int n=5; Range range_2(n);
将数据存储在 std::vector
中
我发现了this,它可以判断一个函数是否是constexpr。但我不清楚如何将其迁移到变量。有人可以帮助我吗?
std::array
需要编译时常量,即使在常量表达式中,函数参数也不是 constexpr。
所以用你的界面是不可能的。
如果您同意
Range range_1(std::integral_constant<std::size_t, 10>{});
,您可以这样做:
template <std::size_t N>
using IC = std::integral_constant<std::size_t, N>;
constexpr std::size_t dynamic_extent = -1;
template <std::size_t N>
struct Range
{
Range(IC<N>) {}
std::array<int, N> data{};
};
template <>
struct Range<dynamic_extent>
{
Range(std::size_t N) : data(N) {}
std::vector<int> data;
};
// CTAD
template <std::size_t N> Range(IC<N>) -> Range<N>;
Range(std::size_t) -> Range<dynamic_extent>;
// Testing
Range r1(IC<10>{});
Range r2(10);
static_assert(std::is_same_v<decltype(r1.data), std::array<int, 10>>);
static_assert(std::is_same_v<decltype(r2.data), std::vector<int>>);