考虑一个例子:
#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)
从带括号的左值推导应根据[cl.type.simple]/4.4推导为左值引用。例如:
decltype(auto) foo(X *x) { // type of result == int&
return (x->x);
}
但是被剪断的会触发 static_assert。即使我们将表达式组合成额外的括号,例如:
return ((ts->x + ...));
它不会改变效果。
标准中是否有一点可以防止将单个元素的折叠表达式扣除到左值引用中?
编辑
作为Johannes Schaub 的一个重要观点 - litb clang 实际上确实将代码的双括号版本解释为带括号的左值并推断出左值引用。在这种情况下,我会将其解释为 gcc 错误。然而,带有单括号版本的版本仍然存在问题。令我困惑的是,至少在一个以上元素的情况下,版本必须转换为带括号的代码 - 以满足运算符优先级。例如:
(x + ...)*4 -> (x1 + x2)*4
不一致的原因是什么?