Return 来自 lambda 的 lambda

Return a lambda from a lambda

我想使用 lambda 来评估(切换大小写)某些条件,并 return 相应地使用 lambda。

const auto lmb1 = []() {
    printf("1\n");
};

const auto lmb2 = []() {
    printf("2\n");
};

const auto select = [](auto const &ref) {
  switch(ref) {
      case 1: return lmb1;
      case 2: return lmb2;
  }
  
    
};

std::function foo = select(1);

foo();

遗憾的是,一切都无法正常工作。
我哪里错了?

问题是 lambda 默认推导(作为 auto 函数)returned 类型,而在您的 lambda 中您 return 两个不同的 lambda。每个 lambda 都有不同的类型,因此编译器无法为 returned lambda

选择类型
[](auto const &ref) {
  switch(ref) {
      case 1: return lmb1; //    decltype(lmb1) 
      case 2: return lmb2; // != decltype(lmb2)
  }  
};

您可以通过不同的方式解决问题。

  1. 您可以使用 lmb1lmb2 都可以转换为的类型来明确 lambda returned 类型(在本例中,std::function<void()>void(*)())。当该类型可用时

    // -----------------vvvvvvvvvvvvvvvvvvvvvvvv
    [](auto const &ref) -> std::function<void()> {
         switch(ref) {
             case 1: return lmb1; 
             case 2: return lmb2;
         }  
    };
    
  2. 您可以明确地将 returned 值转换为通用类型。同样:当有通用类型可用时

    [](auto const &ref)
    {
        switch(ref) { // --V
            case 1: return +lmb1; // with the '+', lmb1 is converted to a void(*)()
            case 2: return +lmb2; // with the '+', lmb2 is converted to a void(*)()
    }     // --------------^
    
  3. 如果 ref 参数可以是一个模板值,从 开始你可以定义一个模板 lambda,然后使用 if constexpr,你可以 return 来自不同 lambda 的不同类型。这在没有通用类型时也有效(但需要 compile-time 已知参数

    const auto selct = []<int REF>(std::integral_constant<int, REF>) {
      if constexpr ( 1 == REF )
        return lmb1;
      else
        return lmb2;
    };
    
    auto foo = selct(std::integral_constant<int, 1>{});