简体   繁体   English

基于C ++范围的for loop over valarray rvalue不起作用

[英]C++ range-based for loop over valarray rvalue is not working

I would like to iterate over a temporary valarray, but it isn't working. 我想迭代一个临时的valarray,但它不起作用。 Here is my (non-working) code: 这是我的(非工作)代码:

#include <iostream>
#include <valarray>
int main()
{
        using namespace std;
        valarray<int> numerators = {99, 26, 25};
        valarray<int> denominators = {9, 2, 5};
        for (int i : numerators / denominators) { cout <<  i << ","; }
        // lots of errors
        return 0;
}

Below is a minimal working example of what I would like to achieve, except that I don't want to define an object like temp_array . 下面是我想要实现的最小工作示例,除了我不想定义像temp_array这样的对象。

#include <iostream>
#include <valarray>
int main()
{
        using namespace std;
        valarray<int> numerators = {99, 26, 25};
        valarray<int> denominators = {9, 2, 5};
        valarray<int> && temp_array = numerators / denominators;
        for (int i : temp_array) { cout << i << ","; }
        // prints 11,13,5,
        return 0;
}

My compiler is g++ version 4.8.5 (Red Hat 4.8.5-4). 我的编译器是g ++版本4.8.5(Red Hat 4.8.5-4)。 I am compiling with the -std=c++0x flag. 我正在使用-std = c ++ 0x标志进行编译。

I've tried other syntax such as for (auto&& i : temp_array) and for (int const & i : temp_array) , but it doesn't work. 我尝试过其他语法,例如for (auto&& i : temp_array)for (int const & i : temp_array) ,但它不起作用。

From the documentation (which also includes the official way to do this in a single expression): 从文档(其中还包括在单个表达式中执行此操作的官方方法):

Unlike other functions that take std::valarray arguments, begin() cannot accept the replacement types (such as the types produced by expression templates) that may be returned from expressions involving valarrays: std::begin(v1 + v2) is not portable, std::begin(std::valarray(v1 + v2)) has to be used instead. 与采用std :: valarray参数的其他函数不同,begin()不能接受可能从涉及valarrays的表达式返回的替换类型(例如表达式模板生成的类型): std :: begin(v1 + v2)不可移植,必须使用std :: begin(std :: valarray(v1 + v2))。

The intent of this function is to allow range for loops to work with valarrays, not to provide container semantics. 此函数的目的是允许循环范围与valarray一起使用,而不是提供容器语义。

As to what might be the reason, there's also this (which was pointed out by @chris): 至于可能是什么原因,还有这个(@chris指出):

[arithmetic operators] can be implemented with the return type different from std::valarray. [算术运算符]可以使用与std :: valarray不同的返回类型来实现。

So there's technically nothing to guarantee that what returns can safely be passed on to std::begin . 因此,从技术上讲,没有什么可以保证返回的内容可以安全地传递给std::begin

As pointed out in @Yam Marcovivc's answer the operation result isn't guaranteed to be a std::valarray<int> that can be passed directly to std::begin() . 正如在@Yam Marcovivc的回答中指出的那样,操作结果不能保证是std::valarray<int> ,可以直接传递给std::begin() A temporary constructed object does the trick: 临时构造的对象可以解决这个问题:

#include <iostream>
#include <valarray>
int main()
{
        using namespace std;
        valarray<int> numerators = {99, 26, 25};
        valarray<int> denominators = {9, 2, 5};
        for (int i : valarray<int>(numerators / denominators)) { 
            cout <<  i << ","; 
        }
        return 0;
}

See a Live Demo 观看现场演示

    for (int i : (valarray<int> &&)(numerators / denominators)) { cout << i << ","; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM