考虑以下 MCVE,其中我有两个值数组,其中w
是两次v
(在这里尝试一下 https://godbolt.org/z/JkXPNN):
#include <valarray>
using namespace std;
int main() {
valarray<int> v { 1, 2, 3 };
for ([[maybe_unused]] auto x : v) {} // Ok
auto w = v * 2; // Leads to failure in loop below
//valarray<int> w = v * 2; // Works
//auto w = v*=2; // Works
//auto w = v; w *= 2; // Works
for ([[maybe_unused]] auto x : w) {} // Failure here
}
此示例无法在最后一个循环中使用 clang 和 gcc 进行编译(此处为 gcc 输出):
error: no matching function for call to 'begin(std::_Expr<std::__detail::_BinClos<std::__multiplies, std::_ValArray, std::_Constant, int, int>, int>&)'
问题的根源似乎是 dedeced 类型v * 2
(我认为因为显式写下类型是有效的,所以似乎正在发生一些隐式转换)。
看着参考笔记 https://en.cppreference.com/w/cpp/numeric/valarray/operator_arith3#Note, 看起来operator*
可能会返回不同于std::valarray<T>
。
我不明白其中的原因,但更令人费解的是这似乎同样适用于operator*= https://en.cppreference.com/w/cpp/numeric/valarray/operator_arith2#Notes,除了这里我的auto
作业作品。我期望的返回值是operator*=
and operator*
此处相同(增量参考)。
所以我的问题是:
- 这是一个实施问题/错误吗?或者我错过了什么?
- 背后的理由是什么参考笔记 https://en.cppreference.com/w/cpp/numeric/valarray/operator_arith3#Note(例如,为什么操作员可以返回一些不同的东西,这些东西可能不适用于
std::begin
/std::end
)?
(注:我将此问题标记为 c++11,但它似乎也适用于 17 之前的所有版本)