【问题标题】:C++ range-based for loop over valarray rvalue is not workingC ++基于范围的for循环对valarray rvalue不起作用
【发布时间】:2016-05-06 03:44:16
【问题描述】:

我想迭代一个临时的 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&amp;&amp; i : temp_array)for (int const &amp; i : temp_array),但它不起作用。

【问题讨论】:

  • valarrayoperator/ 被允许返回一个代理对象作为表达式模板。
  • 显然,我已经离开 C++ 太久了。有人可以解释for(int i : temp_array){} 是如何有效的 for 循环语句吗?不应该是for(init;end_condition;increment)之类的吗?
  • @user1717828 查看 C++11 的基于范围的 for 循环。

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


【解决方案1】:

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

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

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

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

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

所以从技术上讲,没有什么可以保证返回的内容可以安全地传递给std::begin

【讨论】:

    【解决方案2】:

    正如@Yam Marcovivc's answer 中所指出的,运算结果不能保证是可以直接传递给std::begin()std::valarray&lt;int&gt;。临时构造的对象可以解决问题:

    #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

    【讨论】:

      【解决方案3】:
          for (int i : (valarray<int> &&)(numerators / denominators)) { cout << i << ","; }
      

      【讨论】:

      • 有效,但推荐 c 风格的演员表可能不是最好的建议。同样只是发布代码而没有任何进一步的解释(并且是指其他答案)并不能使这成为一个很好的答案。
      猜你喜欢
      • 1970-01-01
      • 2013-01-04
      • 2016-10-31
      • 1970-01-01
      • 2011-06-23
      • 2011-03-01
      • 2021-04-08
      相关资源
      最近更新 更多