【发布时间】:2020-04-21 09:47:24
【问题描述】:
我正在学习结构化绑定声明。我的理解是,在auto& [x, y] = expr; 中,变量x 和y 被引入类型“引用std::tuple_element<i, E>::type”(对于i=0, 1 和E 是不可见变量e 的类型)。而且,这些变量都是用get<i>(e)初始化的。
所以,如果我使用 auto& 并且 get<> 返回一个值(不是引用),它不应该编译,因为您不能将左值绑定到临时值。但是,以下示例在 GCC、Clang 和 Visual Studio 的某些版本中为我构建:
#include <cstddef>
#include <tuple>
#include <type_traits>
struct Foo {
template<std::size_t i>
int get() { return 123; }
};
namespace std {
template<> struct tuple_size<Foo> : integral_constant<size_t, 1> {};
template<std::size_t i> struct tuple_element<i, Foo> { using type = int; };
}
int main() {
Foo f;
auto& [x] = f;
x++;
}
此外,C++ Insights 清楚地表明,clang 将结构化绑定扩展为:
Foo f = Foo();
Foo & __f17 = f;
std::tuple_element<0, Foo>::type x = __f17.get<0>();
x++;
在这里,它声明x 不是作为引用,而是作为值。这是为什么呢?
我预计左值引用和编译错误:e(上例中的__f17)是左值引用。
【问题讨论】: