63

例:

#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)。

私が知る限り、これは私が直面しているものです。削除された代入演算子を使用しようとして失敗しています。簡単な回避策があるかどうか、さらに広く言えば、一般的にラムダでコピーの構成可能性を省略できるようにする動機となる論理的根拠が何であるかを知りたいです。

4

5 に答える 5

47

ラムダ式の型 (クロージャー オブジェクトの型でもあります) は、名前のない一意の非共用体クラス型です。

したがって、次のことを行っているようです。

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

std::function同じシグネチャを持つ異なるラムダを同じ変数に割り当てたい場合に使用します。

std::function<void()> f = []{};
f = []{}; //ok
于 2013-09-12T05:21:20.027 に答える
8

各ラムダは異なる匿名の互換性のない型であるため、ラムダを再定義することはできません。それらは、std::functionその型を推測できるテンプレート化された関数 (ctor など) に渡す場合にのみコピーできます。

于 2013-09-12T05:26:52.060 に答える
6

これができない理由は、ラムダ式のコピー代入演算子が削除されたと宣言されているためです。標準のセクション 5.1.2/20 を参照してください。より明確にするために(明確な定義については)、このコードサンプルを参照してください

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;
}

他の回答では、各ラムダには一意の型があることが指摘されていますが、これがそのエラーが発生する理由ではありません。この例は、2 つのラムダが同じ型であっても、コピーできないことを示しています。ただし、それを新しい変数にコピーすることはできます。operator=これが、エラー メッセージが型の違いではなく、欠落について不平を言っている理由です。それぞれのラムダが独自の型を持っていても、あまり役に立ちません。

于 2013-10-30T22:40:38.880 に答える
2

If we could assign one lambda to another lambda of a different type, how do we copy the function bodies/definitions from that lambda to the other one? If we would be so stubborn, then we could use some member std::function-like type to be the one who will be copied. But that would be against the ol' C++ rule of not paying blah blah...

于 2013-09-12T05:40:26.957 に答える