ProgramingTip

C ++ 11에서 허용되지 않는 람다를 재정의하는 이유는 무엇입니까?

bestdevel 2020. 11. 30. 19:24
반응형

C ++ 11에서 허용되지 않는 람다를 재정의하는 이유는 무엇입니까?


예 :

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

— 클로저 유형이 표준 레이아웃 클래스인지 (Clause 9) 또는

— 클로저 유형이 POD 클래스인지 여부 (9 절).

내가 말할 수있는 한, 이것이 내가 맞서고있는 것입니다. 실패한 할당 연산자를 사용했습니다. 쉬운 해결 방법이 있는지, 그리고 일반적으로 람다에 대해 복사 구성을 할 수있는 부여가 무엇인지 알고 싶습니다.


이 두 람다가 동일한 유형을 가지고있는 것이 생각하는 것 같지만 사실이 아닙니다. 각각 고유 한 유형을 만듭니다.

#include <functional>
#include <type_traits>
#include <iostream>

int main() {
  auto test = []{};
  auto test2 = []{};
  std::cout << std::is_same< decltype( test ), decltype( test2 ) >::value << std::endl;
  return 0;
}

인쇄 0합니다. 물론 컴파일러에서 얻는 오류 메시지는 이와 관련하여 조금 더 명확하게 할 수 있습니다.


람다 표현식의 유형 (클로저 객체의 유형이기도 함)은 고유 하고 이름이 지정되지 않은 non-공용체 클래스 유형입니다.

따라서 다음을 수행하는 것과 달라집니다.

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

std::function동일한 서명을 가진 다른 람다를 동일한 변수에 할당하려는 경우 사용 합니다.

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

Lambda를 재정의 할 수 없습니다. std::function해당 유형을 추론 할 수 있는 템플릿 함수 (예 : ctor)에 전달하는 경우에만 복사 할 수 있습니다 .


이를 수행 할 수없는 이유는 lambda-expression에 대한 복사 할당 연산자가 삭제 된 것입니다. 표준의 섹션 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;
}

다른 답변은 각 람다가 고유 한 유형을 가지고 있다고 지적했지만 이것이 그 오류가 발생하는 이유가 아닙니다. 이 예제는 두 개의 람다가 동일한 유형을 가지고 있어도 여전히 복사 할 수 없음을 보여줍니다. 그러나 새 변수에 복사 할 수 있습니다. 이것이 오류 메시지가 operator=유형이 다른 것이 아니라 누락에 대해 불평하는 이유 입니다. 각각의 람다가 자신의 유형을 가지고 있다고해도 많은 도움이되지는 않습니다.


한 람다를 다른 유형의 다른 람다에 할당 할 수 있다면 해당 람다에서 다른 람다로 함수 본문 / 정의를 어떻게 복사합니까? 우리가 그렇게 고집을 std::function부리면 멤버 와 같은 유형을 복사 할 사람으로 사용할 수 있습니다. 그러나 그것은 어쩌구 저쩌구 지불하지 않는 ol 'C ++ 규칙에 위배됩니다 ...

참고 URL : https://stackoverflow.com/questions/18755787/redefining-lambdas-not-allowed-in-c11-why

반응형