C ++ 14에 이미 제네릭 람다가있는 경우 C ++ 20에 도입 된 템플릿 람다의 필요성은 무엇입니까?


99

다음과 같이 작성할 수있는 일반 람다를 도입했습니다.

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

이 일반적인 람다 func는 템플릿 함수 func가 작동 하는 것처럼 작동 한다는 것은 매우 분명합니다 .

C ++위원회가 일반 람다에 대한 템플릿 구문을 추가하기로 결정한 이유는 무엇입니까?


5
인수 또는 반환 유형 과 다른 템플릿 유형 을 사용해야하는 경우 어떻게해야 합니까? 그리고 그것이 신체 내부에 필요하다면?
일부 프로그래머 친구

이것은 흥미로운 사용 사례 라고 들었습니다 .
Max Langhof

다른 람다 버전을 비교하려면 다음을 참조하십시오. modernescpp.com/index.php/more-powerful-lambdas-with-c-20
schoetbi

답변:


115

C ++ 14 제네릭 람다는 operator ()다음과 같은 펑터를 생성하는 매우 멋진 방법입니다 .

template <class T, class U>
auto operator()(T t, U u) const;

하지만 다음과 같지는 않습니다.

template <class T>
auto operator()(T t1, T t2) const; // Same type please

이것도 마찬가지입니다.

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

(실제로 사용하기가 약간 까다로울지라도)

template <class T>
auto operator()() const; // No deduction

C ++ 14 람다는 괜찮지 만 C ++ 20을 사용하면 이러한 경우를 번거 로움없이 구현할 수 있습니다.


2
멋지고 간결합니다. 이것 만 추가하면 첫 번째 (동일한 유형)는 (auto a, decltype(a) b)C ++ 14에서 해결할 수 있습니다 .
Sebastian Mach

13
@SebastianMach 거의. 이 솔루션 b은 추론되지 않으며 인수는 암시 적으로 a대신 유형으로 변환 됩니다.
Quentin

32

C ++ 20에서 템플릿 기반 람다를 사용할 수 있으므로 SFINAE 식보다 더 쉬운 방법으로 형식을 제한 할 수 있습니다.

auto lambda = []<typename T>(std::vector<T> t){};

이 람다는 벡터 유형에서만 작동합니다.


8
consteval새 구문과 는 어떤 관련이 있습니까? 멋지고 모든 것이지만 관련성을 얻지 못합니다.
StoryTeller-Unslander Monica

그것은 더 많은 질문에 대한 답변보다 람다 식에 어떤 C ++ (20) 추가에 대한 정보입니다
앙투안 Morrier

24

C ++ 20에 채택 된 제안 에는 예제와 함께 긴 동기 부여 섹션이 있습니다. 전제는 다음과 같습니다.

제네릭 람다를 정의하는 현재 구문이 저자에 의해 불충분하다고 간주되는 몇 가지 주요 이유가 있습니다. 요점은 일반 함수 템플릿으로 쉽게 수행 할 수있는 일부 작업은 일반적인 람다로 수행하기 위해 상당한 후프 점프가 필요하거나 전혀 수행 할 수 없다는 것입니다. 저자는 람다가 C ++이이를 지원할만큼 충분히 가치 있다고 생각합니다. 일반 기능 템플릿뿐만 아니라

다음은 몇 가지 예입니다.


21

C ++ 20에 도입 된 람다에 대한 새로운 "익숙한 템플릿 구문"은  C ++ 17 대안에 비해와 같은 구조  for_types 를  for_range실행 가능하고 더 읽기 쉽게 만듭니다.

(출처 : C ++ 20 람다를 사용한 컴파일 타임 반복 )

C ++ 14 및 C ++ 17 일반 람다 모두에서 수행 할 수있는 또 다른 흥미로운 것은 operator() 템플릿 매개 변수를 명시 적으로 전달하여 직접 호출  하는 것입니다.

C ++ 14 :

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20 :

  auto l = []<typename T>(){ };
  l.template operator()<int>();

위의 C ++ 14 예제는 매우 쓸모가 없습니다. operator() 인수에 이름을 지정하고를 사용하지 않고는 람다 본문에  제공된 유형을 참조 할 방법이 없습니다  decltype. 또한 우리는 필요하지 않더라도 인수를 전달해야합니다.

C ++ 20 예제는 람다 본문에서 T에 쉽게 액세스 할 수있는 방법과 이제 nullary 람다를 임의로 템플릿화할 수 있음을 보여줍니다. 이것은 앞서 언급 한 컴파일 타임 구조의 구현에 매우 유용 할 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.