Consider the following MCVE, where I have two value arrays where w
is two times v
(check it out here):
#include <valarray>
using namespace std;
int main() {
valarray<int> v { 1, 2, 3 };
for (auto x : v) { (void)x; } // Ok
auto w = v * 2; // Leads to failure in range based loop below
//valarray<int> w = v * 2; // Works
//auto w = v*=2; // Works, but modifies v as well
//auto w = v; w *= 2; // Works
for (auto x : w) { (void)x; } // Failure here
}
This example fails to compile with clang and gcc at the last loop with (gcc output here):
error: no matching function for call to 'begin(std::_Expr<std::__detail::_BinClos<std::__multiplies, std::_ValArray, std::_Constant, int, int>, int>&)'
The source of the problem seems to be the decuced type of v * 2
(I assume that because explicitly writing down the type works, so some implicit conversion seems to be taking place).
Looking at the reference notes, it seems that operator*
may return something different than std::valarray<T>
. To be honest, I don't understand the reason for this but what confuses me even more is that the same notes seem to apply to operator*=
, except that here my auto
assignment works. I would expect the return values of operator*=
and operator*
to be the same here (delta reference).
So my questions are:
- Is this an implementation issue/bug? Or am I missing something?
- What's the rationale behind the reference notes (e.g. why can the operators return something different that may not work with
std::begin
/std::end
?
(Note: I tagged this question c++11, but it seems to apply to all versions up to 17 as well)
Aucun commentaire:
Enregistrer un commentaire