亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在默認情況下,為什么C ++ 11的lambda要求“可變”關鍵字來進行按值捕獲?

在默認情況下,為什么C ++ 11的lambda要求“可變”關鍵字來進行按值捕獲?

C++
墨色風雨 2019-10-05 14:03:54
簡短示例:#include <iostream>int main(){    int n;    [&](){n = 10;}();             // OK    [=]() mutable {n = 20;}();    // OK    // [=](){n = 10;}();          // Error: a by-value capture cannot be modified in a non-mutable lambda    std::cout << n << "\n";       // "10"}問題:為什么我們需要mutable關鍵字?與傳遞給命名函數的傳統參數完全不同。背后的原理是什么?我給人的印象是,按值捕獲的全部目的是允許用戶更改臨時值-否則,使用按引用捕獲幾乎總是更好,不是嗎?有什么啟示嗎?(順便說一句,我正在使用MSVC2010。AFAIK,這應該是標準的)
查看完整描述

3 回答

?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

您的代碼幾乎與此等效:


#include <iostream>


class unnamed1

{

    int& n;

public:

    unnamed1(int& N) : n(N) {}


    /* OK. Your this is const but you don't modify the "n" reference,

    but the value pointed by it. You wouldn't be able to modify a reference

    anyway even if your operator() was mutable. When you assign a reference

    it will always point to the same var.

    */

    void operator()() const {n = 10;}

};


class unnamed2

{

    int n;

public:

    unnamed2(int N) : n(N) {}


    /* OK. Your this pointer is not const (since your operator() is "mutable" instead of const).

    So you can modify the "n" member. */

    void operator()() {n = 20;}

};


class unnamed3

{

    int n;

public:

    unnamed3(int N) : n(N) {}


    /* BAD. Your this is const so you can't modify the "n" member. */

    void operator()() const {n = 10;}

};


int main()

{

    int n;

    unnamed1 u1(n); u1();    // OK

    unnamed2 u2(n); u2();    // OK

    //unnamed3 u3(n); u3();  // Error

    std::cout << n << "\n";  // "10"

}

因此,您可以將lambda看作是使用operator()生成的類,除非您說它是可變的,否則該類默認為const。


您也可以將[]內部捕獲的所有變量(顯式或隱式)視為該類的成員:[=]對象的副本或[&]對象的引用。當您聲明lambda時就將它們初始化,就像有一個隱藏的構造函數一樣。


查看完整回答
反對 回復 2019-10-05
?
守著星空守著你

TA貢獻1799條經驗 獲得超8個贊

我給人的印象是,按值捕獲的全部目的是允許用戶更改臨時值-否則,使用按引用捕獲幾乎總是更好,不是嗎?


問題是,它“幾乎”嗎?常見的用例似乎是返回或傳遞lambda:


void registerCallback(std::function<void()> f) { /* ... */ }


void doSomething() {

  std::string name = receiveName();

  registerCallback([name]{ /* do something with name */ });

}

我認為這mutable不是“幾乎”的情況。我認為“按值捕獲”類似于“允許我在捕獲的實體死亡后使用其值”,而不是“允許我更改其副本”。但這也許可以爭論。


查看完整回答
反對 回復 2019-10-05
  • 3 回答
  • 0 關注
  • 547 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號