使用 tie 从元组分配 2 个 lambda

Assigning 2 lambdas from a tuple using tie

我有一个 returns 一个 std::tuple lambda 的函数,我想使用 std::tie()

将每个 lambda 分配给一个变量
#include<tuple>
#include <iostream>
using namespace std;

auto fn(){
    auto f1 = []() {cout << "ran 1" << endl;};
    auto f2 = []() {cout << "ran 2" << endl;};
    return make_tuple(f1, f2);
}

int main()
{
    auto res = fn();
    auto f1,f2; // doesn't compile
    tie(f1, f2) = res;

    f1();
    f2();
    return 0;
}

问题是 lambda 必须来自类型“auto”,因为它们是在编译时解析的,但我不能在不定义变量的情况下将变量声明为 auto。那么我该怎么做才能编译这段代码呢?

C++17 引入了 structured bindings,它将为您完成这项工作。使用

const auto& [f1, f2] = fn();

将创建对返回对象的引用以延长其生命周期,并引入 f1f2 作为元组成员的名称。

从 C++17 开始,您可以使用结构化绑定(参见其他答案)。

在 C++17(C++11 和 C++14)之前,您可以使用带有两个单独声明的 std::get()

auto f1 = std::get<0>(res);
auto f2 = std::get<1>(res);

并且,是的:在这两种情况下,您必须同时声明和定义变量[编辑:在 C++20 之前都是如此;自 C++20 以来不一定为真]

因为可以获得f1f2的类型,所以加倍使用std::get()

using type_f1 = std::remove_reference_t<decltype((std::get<0>(res)))>;
using type_f2 = std::remove_reference_t<decltype((std::get<1>(res)))>;

或者,也许更好,使用 std::tuple_element

using type_f1 = std::tuple_element_t<0, decltype(res)>;
using type_f2 = std::tuple_element_t<1, decltype(res)>;

但这不允许在未定义的情况下声明 f1f2

type_f1  f1;  // compilation error (before C++20) !!!
type_f2  f2;  // compilation error (before C++20) !!!

因为 lambdas 类型缺少 [编辑:在 C++20 之前] 默认构造函数。

编辑:正如 Nathan Oliver 所指出的(谢谢!),从 C++20 开始,具有空捕获列表的 lambda 已启用默认构造函数。

所以,从C++20开始,编译以下代码

#include <tuple>
#include <iostream>

auto fn ()
 { return std::make_tuple(
      []() { std::cout << "ran 1" << std::endl; },
      []() { std::cout << "ran 2" << std::endl; }); }

int main()
 {
   auto res = fn();

   std::tuple_element_t<0u, decltype(res)>  f1;
   std::tuple_element_t<1u, decltype(res)>  f2;

   f1 = std::get<0u>(res);
   f2 = std::get<1u>(res);

   f1();
   f2();
 }