type - lambda c++用法




在C++ 11中不允許重新定義lambda,為什麼? (4)

lambda表達式的類型(也是閉包對象的類型)是一個唯一的 ,未命名的非聯合類類型

所以就像你正在做以下事情:

struct {} a;
struct {} b;
a = b; // error, type mismatch

如果要將具有相同簽名的不同lambda分配給同一變量,請使用std::function

std::function<void()> f = []{};
f = []{}; //ok

例:

#include <functional>

int main() {
  auto test = []{};
  test = []{};

  return 0;
}

這會在gcc 4.7.2中發出以下錯誤消息:

test.cpp: In function ‘int main()’:
test.cpp:5:13: error: no match for ‘operator=’ in ‘test = <lambda closure object>main()::<lambda()>{}’
test.cpp:5:13: note: candidate is:
test.cpp:4:16: note: main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&) <deleted>
test.cpp:4:16: note:   no known conversion for argument 1 from ‘main()::<lambda()>’ to ‘const main()::<lambda()>&’

從標準5.1.2.3(強調我的):

實現可以定義閉包類型與下面描述的不同,前提是這不會改變程序的可觀察行為,只需更改:

- 封閉類型的尺寸和/或對齊方式,

- 封閉類型是否可以輕易複製 (第9條)

- 閉包類型是否為標準佈局類(第9條),或

- 閉包類型是否為POD類(第9條)。

據我所知,這就是我遇到的情況。 它試圖使用已刪除的賦值運算符並失敗。 我很想知道是否有一個簡單的解決方法,更廣泛地說,一般來說,為lambdas省略複製可構造性的動機理由是什麼。


Lambda無法重新定義,因為每個lambda都是不同的,匿名的,不兼容的類型。 只有將它們傳遞給能夠推導出該類型的模板化函數(如std::function ctor)時,才能複制它們。


如果我們可以將一個lambda分配給另一個不同類型的lambda,我們如何將函數體/定義從該lambda複製到另一個? 如果我們如此固執,那麼我們可以使用一些成員std::function -like類型來複製它。 但那將是反對不支付等等等等的'C ++規則...


您無法執行此操作的原因是因為聲明了lambda表達式的複制賦值運算符已被刪除,請參閱標準的第5.1.2 / 20節。 為了更清楚(對於不尋常的clear的定義),請參閱此代碼示例

template<class T> void f(T x1)
{
  T x2 = x1; // copy constructor exists, this operation will succeed.
  x2 = x1; // assignment operator, deleted and will cause an error
}
int main()
{
  f([]{});
  return 0;
}

其他答案指出每個lambda都有一個唯一的類型,但這不是你得到這個錯誤的原因。 此示例顯示即使兩個lambdas具有相同的類型,它仍然無法複製它。 但是,您可以將其複製到新變量。 這就是您的錯誤消息抱怨缺少operator=而不是它們的類型不同的原因。 雖然每個擁有它自己類型的lambda也沒有幫助你。





language-lawyer