昨天我在这里看到an interesting question关于结构化绑定的问题 我们可以总结如下。请考虑以下示例代码:
#include <tuple>
#include <type_traits>
int main() {
auto tup = std::make_tuple(1, 2);
auto & [ a, b ] = tup;
// the following line won't compile for a isn't a reference
// static_assert(std::is_reference_v<decltype(a)>);
}
在这种情况下,由于this bullet(工作草案),decltype(a)
(可能)int
:
如果
e
是一个未加括号的id-expression,命名一个结构化绑定[...],decltype(e)
是结构化绑定声明规范中给出的引用类型
Here是@Curious在感兴趣的评论中提供的wandbox片段。它表明实际上a
不是参考,仅此而已
到目前为止,原始问题非常好,OP问为什么它是int
而不是int &
而标准说看起来像是一个可接受的答案。
无论如何,我想知道委员会为何如此决定。在一天结束时,a
引用元组中的元素,我可以通过a
修改该元素。换句话说,a
的声明看起来像是一个引用,它的行为类似于引用,但它不是引用。
我可以忍受这个,但我想知道背后的原因是什么。为什么decltype(a)
不能简单int &
?亵渎者能理解是否有一个有意义的理由?
答案 0 :(得分:10)
decltype(x)
,其中x
是结构化绑定,为引用命名 结构化绑定的类型。在类似元组的情况下,这就是std::tuple_element
返回的类型,可能不是引用 即使结构化绑定本身实际上总是如此 在这种情况下参考。这有效地模仿了行为 绑定到非静态数据成员具有类型的结构 由tuple_element
返回,具有绑定的参考性 本身只是一个实施细节。
答案 1 :(得分:-1)
之前已经讨论过这个主题(查看结构化绑定标记),您在第二个答案中解决了您正在谈论的行为。但是,理由在p0144r2第3.5节
中详细说明是否应将语法扩展为允许
public static IEnumerable<IEnumerable<T>> SubSetsOf<T>(IEnumerable<T> source) { if (!source.Any()) return Enumerable.Repeat(Enumerable.Empty<T>(), 1); var element = source.Take(1); var haveNots = SubSetsOf(source.Skip(1)); var haves = haveNots.Select(set => element.Concat(set)); return haves.Concat(haveNots); } private static bool Valid(IEnumerable<int> set) { bool flag = false; foreach (var element in set) { var f = element > 0; if (f == flag) { return false; } flag = f; } return true; }
- 符合条件的个人 名称&#39;类型?例如:
const/&
我们认为答案应该是否定的。这是一个存储的简单功能 value并将名称绑定到其组件,而不是声明多个 变量。允许这样的资格将是特征蠕变, 将功能扩展为不同的东西,即一种方式 声明多个变量。
如果我们确实要声明多个变量,我们已经有办法了 拼写:
auto [&x, const y, const& z] = f(); // NOT proposed