Consider an example:
#include <type_traits>
template <class... Ts>
decltype (auto) foo(Ts... ts) {
return (ts->x + ...);
}
struct X {
int x;
};
int main() {
X x1{1};
static_assert(std::is_reference_v<decltype(foo(&x1))>);
}
decltype(auto)
deduced from parenthesized lvalue should according to [cl.type.simple]/4.4 be deduced to lvalue reference. E.g.:
decltype(auto) foo(X *x) { // type of result == int&
return (x->x);
}
But the snipped triggers static_assert. Even if we compose expression into additional parentheses, e.g.:
return ((ts->x + ...));
It doesn't change the effect.
Is there a point in the standard that prevents deduction of a fold-expression of a single element into the lvalue reference?
Edit
As a great point of Johannes Schaub - litb clang actually does interpret the double-parens-version of the code as parenthesized lvalue and deduce lvalue reference. I'd interpret it as a gcc bug in this case. The version with single-parens-version is however still under the question. What puzzles me is that the version must be transformed into a parenthesized code at least in case of more than one element - to fulfil operator precedence. E.g.:
(x + ...)*4 -> (x1 + x2)*4
What is the reason of the inconsistency?