[英]Check number of elements given to std::array compile time
I have a performance critical code where I query N indices. 我有一个性能关键代码,我查询N个索引。 How can I check compile-time with a static_assert
whether exactly N indices are given, without sacrificing performance? 如何在不牺牲性能的情况下使用static_assert
检查编译时是否给出了N个索引?
#include <array>
template<int N>
void test(const std::array<int, N>& indices)
{
// static_assert: has three elements.
return;
}
int main()
{
test<3>({1, 2, 3}); // OK
test<3>({1, 2}); // Needs to crash, because 2 < 3
test<2>({1, 2, 3}); // Crashes, because 3 > 2
test<2>({1, 2}); // OK
return 0;
}
How can I check compile-time with a static_assert whether three indices are given 如何使用static_assert检查编译时是否给出了三个索引
You can't. 你不能。 They array is of size 3 so it will always have 3 elements. 它们的数组大小为3,因此它总是有3个元素。 When you do something like 当你做类似的事情
test({1, 2});
The array initializes the first two elements with 1
and 2
and then zero-initializes the last element. 数组使用1
和2
初始化前两个元素,然后对最后一个元素进行零初始化。 This is how aggregate initialization works and you can't change it. 这是聚合初始化的工作方式,您无法更改它。
What you need to do is either add overloads for arrays of size 1 and 2 and delete them, or you could just change the function to have 3 parameters and then it must be called with 3 values. 您需要做的是为大小为1和2的数组添加重载并删除它们,或者您可以只更改函数以包含3个参数,然后必须使用3个值调用它。
Here's one way to do it: 这是一种方法:
#include <array>
#include <iostream>
template<int N, typename ...Args>
void test(Args... args)
{
static_assert(sizeof...(args) == N);
std::array<int, N> arr{ args... };
for (auto&& elm : arr) {
std::cout << elm << '\n';
}
}
int main()
{
test<3>(1, 2, 3); // OK
//test<3>(1, 2); // Crashes
//test<2>( 1, 2, 3 ); // Crashes
test<2>(1, 2); // OK
return 0;
}
Uses variadic templates instead. 使用可变参数模板。
A bit ugly, but should work - a wrapper for std::array
: 有点难看,但应该工作 - std::array
的包装:
class MyArray
{
public:
MyArray(int x, int y, int z): _array{x, y, z}
{};
private:
std::array<int, 3> _array;
};
void test(const MyArray&) {
//no need to check values here
}
You won't be able to create an object of this wrapper class with less than 3 arguments. 您将无法使用少于3个参数创建此包装类的对象。 See it online . 在线查看 。
Of course, it won't work for general case you mentioned, but it should make it possible to differentiate certain classes. 当然,它不适用于您提到的一般情况,但它应该可以区分某些类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.