结构化绑定以替换std :: tie滥用 [英] Structured binding to replace std::tie abuse

查看:348
本文介绍了结构化绑定以替换std :: tie滥用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读摘要c ++ 17的最终功能让我对结构化绑定(强调我的)这一部分感到有些惊讶:

结构化绑定

到目前为止,有一个已知的技巧可以滥用std :: tie直接将元组或对分配给不同的变量,而不必手动处理结果类型. 这是一个黑客,而且变量也必须存在,现在您可以声明变量并将其初始化为一行:

auto [a,b,c] = getvalues();

需要大括号,getvalues返回一个元组.提案中未提及std :: pair,因此尚不清楚它是否适用于pair,这是STL在某些插入方法中返回的.

我假设他们指的是std::tie

的这种用法

int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);

我认为这是推荐做法.

有人可以解释为什么他们将上述示例称为黑客吗?

解决方案

我可以这样简单地说:

在一种语言中,函数只能返回一个变量

int a,b,c;
std::tie(a,b,c) = function_returning_multiple_values();

是针对以下情况的黑客手段:

auto [a, b, c] = function_returning_multiple_values();

就像在C ++只允许一个函数参数的假设世界中一样

int p1, p2, p3;
p1 = ...;
p2 = ...;
p3 = ...;

function_taking_multiple_params(std::tie_params(p1, p2, p3));

将成为以下用途的黑客

function_taking_multiple_params(p1, p2, p3)


您非常习惯C ++限制,因此一个函数最多可以返回一个对象,但是实际上,这只是一种人工语言限制,就像接受最多一个参数的限制就是一种人工语言限制一样./p>

std::tie是缺少语言功能的库黑客.而且它有一些缺点:

  • 变量需要事先声明
  • 必须明确声明变量类型
  • 效率低下或不能与默认不可构造的类型一起使用

结构化绑定是否本来可以做的一切?不,但是在大多数情况下,它们是我们所需要的.

缺少什么?

  • 某些元素的显式类型:例如:

auto [a, std::string b, c] = foo();

其中ac具有推论的类型,而b是显式的"std :: string"

  • 嵌套.例如:

auto [a, [b1, b2], c] = foo();

其中从foo返回的第二个对象是类似tuple的对象.

  • 返回站点的语言功能(一起绕过std::tuple):

auto foo() -> [int, int]

代替

auto foo() -> std::tuple<int, int>

  • 命名返回对象

auto foo() -> [int& key, int& value]

...好吧...那不是很好

  • 并将其与...结合-准备一个很酷的新名称-通用返回初始化:

auto minmax_element(It begin, It end) -> [It min_it, It max_it];

auto [min = *min_it, max = *max_it] = minmax_element(...);

In reading this summary of the c++17 final features I was a bit surprised by the section on structured bindings (emphasis mine):

structured bindings

Until now, there was a known trick to abuse std::tie to assign a tuple or pair to different variables directly, instead of having to deal with the result type manually. This was a hack, and also the variables had to exist, now you can declare the variables and initialize them in one line:

auto [a , b , c] = getvalues();

The braces are needed, getvalues returns a tuple. std::pair is not mentioned in the proposal, so its unclear if this works with pair, which is returned by the STL in some insert methods.

I am assuming they refer to this kind of usage of std::tie

int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);

which I believed to be a recommended practice.

Can someone offer an explanation as to why they are referring to above example as a hack?

解决方案

I can put it simply like that:

In a language where functions can return just one variable

int a,b,c;
std::tie(a,b,c) = function_returning_multiple_values();

is a hack for:

auto [a, b, c] = function_returning_multiple_values();

just as in the hypothetical world where C++ would allow just one parameter for functions

int p1, p2, p3;
p1 = ...;
p2 = ...;
p3 = ...;

function_taking_multiple_params(std::tie_params(p1, p2, p3));

would be a hack for:

function_taking_multiple_params(p1, p2, p3)


You are so accustomed with the C++ restriction that a function can return at most one object, but in fact it is just an artificial language restriction, just as a restriction to accept at most one parameter would be an artificial language restriction.

The std::tie is a library hack for a missing language feature. And it has some drawbacks:

  • the variables need be declared beforehand
  • the variable types must be declared explicitly
  • Inefficient or can't be used with types that are not default constructible

Are structured bindings everything that they could have been? No, but for the most cases they are everything we need.

What is missing?

  • Explicit type for some elements: e.g.:

auto [a, std::string b, c] = foo();

where a and c have the type deduced and b is explicit "std::string"

  • Nesting. E.g.:

auto [a, [b1, b2], c] = foo();

where the second returned object from foo is a tuple like object.

  • Language feature at the return site (bypassing std::tuple all together):

auto foo() -> [int, int]

instead of

auto foo() -> std::tuple<int, int>

  • Named return objects

auto foo() -> [int& key, int& value]

... well... wouldn't that be nice

  • and combine that with... - get ready for a cool new name - Generalized return initialization:

auto minmax_element(It begin, It end) -> [It min_it, It max_it];

auto [min = *min_it, max = *max_it] = minmax_element(...);

这篇关于结构化绑定以替换std :: tie滥用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆