1

我有一个简单的用法来遍历std::valarray范围 for 循环中的临时表达式,但得到error:无效范围表达式...

主文件

#include <iostream>
#include <valarray>

int main()
{

    std::valarray<int> xxx {2,7,1,8,2,8};
    std::valarray<int> zzz {xxx};

    for (auto x : xxx + zzz) std::cout << x << std::endl;

    return 0;
}

clang++ main.cpp -std=c++11

main.cpp:10:17: error: invalid range expression of type 'std::__1::__val_expr<std::__1::_BinaryOp<std::__1::plus<int>, std::__1::valarray<int>, std::__1::valarray<int> > >'; no viable 'begin' function available
    for (auto x : xxx + zzz) std::cout << x << std::endl;
                ^ ~~~

它没有按我预期的那样编译真的有充分的理由吗? 重载的返回类型operator+valarray<T>,所以理论上,表达式的值应该是 type 的临时实例valarray<T>

概要:

template<class T> valarray<T> operator+ (const valarray<T>& x, const valarray<T>& y);

版本: Apple LLVM 版本 8.0.0 (clang-800.0.38) 目标:x86_64-apple-darwin15.6.0

注意以下线路工作

for (auto x : xxx += zzz) std::cout << x << std::end;
4

4 回答 4

1

由于“开始”和“结束”可用于operator+返回类型,即valarray<T>我会说错误是错误的,它应该编译。

于 2016-11-11T10:47:40.303 回答
0

这是一个非常好的问题。原因是 A+B 在 valarrays 上的行为。

让我们看看我的意思。

首先,尝试这些行。

std::valarray<int> xxx {2,7,1,8,2,8};
std::valarray<int> zzz {xxx};
auto t=xxx+zzz;
cout<<typeid(t).name()<<endl;
cout<<typeid(xxx).name()<<endl;
cout<<typeid(xxx+zzz).name()<<endl;

您会注意到它们不一样,这是由于此处 + 运算符的定义https://en.cppreference.com/w/cpp/numeric/valarray/operator_arith3 正如其所写的那样,推断出类型。这意味着它的行为类似于 auto。那么问题是为什么它不推导出相同的类型 valarray。可能是因为编译器优化特性,也可能是一个错误,但很明显,引用并没有强制编译器推导出相同的类型。问题是推导的类型恰好不能被基于范围的 for 循环迭代。

如果有任何不清楚的地方,请告诉我。

于 2019-02-08T21:20:50.087 回答
0

你想让我做什么?如果您想遍历 xxx ,请仅在其中执行:

for (const auto x : xxx) std::cout << x << std::endl;

但是回答您问题的基础知识,表达式 (xxx + yyy) 是不可迭代的。如果要在两者中都执行 for 循环,请执行两个 fors:

for (auto x : xxx) std::cout << x << std::endl;
for (auto x : zzz) std::cout << x << std::endl;

如果你想在一个循环中完成,你可以同时追加

xxx += yyy;
for (auto x : xxx) std::cout << x << std::endl;

来自编辑的 PD:行

for (auto x : xxx += yyy) std::cout << x << std::endl;

之所以有效,是因为它先进行追加,然后进行迭代。相当于我最后的建议。但是 (xxx+yyy) 是不可迭代的。

根据您的评论: valarray::operator+(valarray) 不存在。valarray::operator+=(valarray) 确实存在。

于 2016-11-11T10:24:26.090 回答
0

for 循环的范围使用非成员 std::begin 和 std::end,对于 std::valarray 的 operator+ 的返回类型,它们不需要存在。

可移植语法是

for(auto x : std::valarray<int>(xxx + zzz))

这在cppreference和 26.7.1[valarray.syn]p4.1 下的标准中有所说明

于 2016-11-28T14:10:18.133 回答