考虑以下 MCVE,其中我有两个值数组,其中w
是两次v
(在此处尝试):
#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>&)'
问题的根源似乎是 decuced 类型v * 2
(我假设因为明确写下类型有效,所以似乎正在发生一些隐式转换)。
查看参考说明,似乎operator*
返回的内容可能与std::valarray<T>
. 我不明白这样做的原因,但更令人费解的是,这似乎也适用于operator*=
,除了我的auto
作业在这里有效。我希望 和 的返回值operator*=
在operator*
这里是相同的(增量参考)。
所以我的问题是:
- 这是一个实施问题/错误吗?还是我错过了什么?
- 参考说明背后的基本原理是什么(例如,为什么操作员可以返回可能不适用于
std::begin
/的不同内容std::end
)?
(注意:我标记了这个问题 c++11,但它似乎也适用于 17 及以下的所有版本)