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

时间:2016-01-28 16:39:13

标签: c++ for-loop rvalue temporary-objects valarray

我想迭代一个临时的valarray,但它不起作用。这是我的(非工作)代码:

#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;
}

下面是我想要实现的最小工作示例,除了我不想定义像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;
}

我的编译器是g ++版本4.8.5(Red Hat 4.8.5-4)。 我正在使用-std = c ++ 0x标志进行编译。

我尝试过其他语法,例如for (auto&& i : temp_array)for (int const & i : temp_array),但它不起作用。

3 个答案:

答案 0 :(得分:18)

从文档中(其中还包括在单个表达式中执行此操作的官方方式):

  

与采用std :: valarray参数的其他函数不同,begin()不能接受可能从涉及valarrays的表达式返回的替换类型(例如表达式模板生成的类型): std :: begin(v1 + v2)不可移植,必须使用std :: begin(std :: valarray(v1 + v2))。

     

此函数的目的是允许循环范围与valarray一起使用,而不是提供容器语义。

至于可能是什么原因,还有这个(@chris指出):

  

[算术运算符]可以使用与std :: valarray不同的返回类型实现。

因此,在技术上没有什么能保证返回的内容可以安全地传递给std::begin

答案 1 :(得分:11)

正如@Yam Marcovivc's answer中指出的那样,操作结果不能保证为std::valarray<int>,可以直接传递给std::begin()。临时构造的对象可以解决这个问题:

#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;
}

查看Live Demo

答案 2 :(得分:3)

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