c++ - 取代 std::tie 滥用的结构化绑定(bind)

标签 c++ c++17 stdtuple structured-bindings

阅读中this c++17 最终特性的总结我对结构化绑定(bind)的部分感到有点惊讶(强调我的):

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.

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

的这种用法
int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);

我认为这是推荐的做法。

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

最佳答案

我可以这样简单地说:

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

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++ 的限制如此习以为常,一个函数最多只能返回一个对象,但实际上这只是一种人为的语言限制,就像最多接受一个参数的限制将是一种人为的语言限制一样。

std::tie 是针对缺失语言功能的库 hack。它有一些缺点:

  • 变量需要事先声明
  • 必须显式声明变量类型
  • 效率低下或不能用于非默认可构造的类型

结构化绑定(bind)是它们本来可以成为的一切吗?不,但在大多数情况下,它们就是我们所需要的一切。

缺少什么?

  • 某些元素的显式类型:例如:
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(...);

关于c++ - 取代 std::tie 滥用的结构化绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40241335/

相关文章:

c++ - UDP套接字recvfrom中的访问冲突读取位置

c++ - 为什么取消引用指向 std::set 的提取节点的指针是未定义的行为?

c++ - unordered_map和emplace,为什么ctor被调用两次?

c++ - 返回元组的可变参数模板

c++ - 返回一个 2 元组是否比 std::pair 效率低?

c++ - 如何在 C++ 中使用 MongoDB 地理空间索引

c++ - 在类<std::unique_ptr<B>> 中强制模板函数为 T=B*

C++ 类似于汇编的指针访问

c++ - 使用分配器 C++ 创建元组

c++ - 使用 variant + reference_wrapper + unique_ptr 表达(非)拥有资源的想法