如何在运行时使用array<int,10>或array<int,4>?

4
我希望我的代码可以根据运行时的值,使用数组的短版本或长版本(包含更多元素)。
constexpr std::array<int, 10> longArray{0,1,2,3,4,5,6,7,8,9};
constexpr std::array<int,4> shortArray{0,3,6,9};
auto const& myArray = useShortArray ? shortArray : longArray;
for( auto n : myArray ) {
     // Do the stuff
}

如上所述,由于三元运算符的参数不相同,因此会出现错误。

我该怎么做呢?

唯一的方法是声明两个被赋值的起始和结束迭代器。但这将导致在迭代器上使用旧的for,并要求在for块内的每次使用中取消引用迭代器。

auto const& myBegin = useShortArray ? shortArray.begin() : longArray.begin();
auto const& myEnd   = useShortArray ? shortArray.end()   : longArray.end();
for( auto it = myBegin ; it != myEnd ; ++it ) {
    // use *it
}

有没有一些方法可以编写它(也许是将数组复制到向量中?)以避免回归到最初/结束版本?

1
std::span(C++20)可能会有所帮助(但它主要是begin/end迭代器,但作为范围)。 - Jarod42
1
另一种选择是 template <typename T> SomeType do_job(const T& array) {/*...*/} 然后 return useShortArray ? do_job(shortArray) : do_job(longArray); - Jarod42
1
严格来说,即使 auto begin = useShortArray ? shortArray.begin() : longArray.end()只是偶然能够工作的,因为std::array<T,N>::iterator类型可能取决于 N (并且在 MS STL中确实如此)。 - Kirill Dmitrenko
如何使用array<int,9>或array<int,4>,以及constexpr std::array<int, 10> longArray ;-) - Jarod42
@Jarod42那为什么不用constexpr std::array<int, 13> bothArrays呢? :P - Paul Evans
显示剩余2条评论
1个回答

6
您可以使用lambda,例如:
auto doTheStuff = [](auto& myArray) {
    for(auto n : myArray) {
         // Do the stuff
    }
};

useShortArray ? doTheStuff(shortArray) : doTheStuff(longArray);

或者,如果你想给它一个名称,这可以是模板函数。

另一种方法是使用 span,比如即将在 C++20 中推出的 std::span。在这种方法中,接受不同大小数组的模板函数是 span 的构造函数。这样使用范围的函数就不需要成为模板了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接