簡體   English   中英

將指向lambda函數的指針指定給指向另一個lambda函數的指針

[英]Assigning pointer to lambda function to pointer to another lambda function

我試圖指定一個指向lambda函數的指針指向另一個lambda函數。 代碼將說明一切:

#include <iostream>

int main(int argc, char *argv[]) {

    auto l1 = []() { std::cout << "Lambda 1!" << std::endl; };
    auto l2 = [] { std::cout << "Lambda 2!" << std::endl; };

    auto l1p = &l1;
    l1p = &l2; // Why can't I do this assignment?
    return 0;
}

由於兩個lambda函數的返回類型和參數是相同的,為什么我不能做這個賦值?

[expr.prim.lambda] / 2:

lambda表達式的類型(也是閉包對象的類型)是一個唯一的 ,未命名的非聯合類類型 - 稱為閉包類型 - 其屬性如下所述。

也就是說,兩種閉包類型總是完全不同且不相關。 但是,在您的示例中,由於兩個lambda都沒有捕獲任何內容,因此可以將它們轉換為void(*)()類型的函數指針。
所以也許你打算做

void (*l1p)() = l1;
l1p = l2;

作為Columbo答案的補充,你可以使用operator +同時進行類型推導和lambda-to-function指針衰減:

auto l1p = +l1; // l1p is void (*)()
//         ^
l1p = l2;

讓我們刪除lambda函數為我們提供的語法糖:

struct lambda1 {
  void operator () {
    std::cout << "Lambda 1!" << std::endl;
  }
};
struct lambda2 {
  void operator () {
    std::cout << "Lambda 2!" << std::endl;
  }
};
int main(int argc, char *argv[]) {

    auto l1 = Lambda1{};
    auto l2 = Lambda2{};

    auto l1p = &l1; // l1p is a Lambda1 *
    l1p = &l2; // &l2 is a Lambda2 *
    return 0;
}

這不是編譯器完成的轉換,但我認為檢查問題就足夠了:

這兩個lambda都有自己的類型,與它們的參數,捕獲的變量或返回類型完全無關。 當然,lambda的類型彼此無關,所以你顯然不能從另一個的地址指定一個指針。


使用函數指針解決另一個問題的解決方案非常好。 如果C ++沒有“你只用它為它付錢”的學說,我們就可以把lambda函數做成像

struct SomeLambda
  : public LambdaBase<
        Capture<int>,
        Arguments<bool>,
        Return<void>> {
  // ...
};
/*
  [integer]
  (bool flag) {
    if (flag) cout << integer;
  }
*/

但是為了理所當然,基礎需要是多態的(具有虛擬成員函數),如果你不打算做你想做的事情,這是你不需要的成本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM