program story

클래스 템플릿 파라미터로서의 Lambda 표현식

inputbox 2020. 12. 9. 08:08
반응형

클래스 템플릿 파라미터로서의 Lambda 표현식


람다 식 클래스 템플릿 매개 변수 로 사용할 수 있습니까 ? (이것은 매우 다른 문제 참고 이것 람다 식 자체 템플릿 수 있다면 묻는다).

다음과 같이 할 수 있는지 묻습니다.

template <class Functor> 
struct Foo { };
// ...
Foo<decltype([]()->void { })> foo;

예를 들어 클래스 템플릿 equal_to에 일반적으로 한 줄 펑터로 구현되는 다양한 매개 변수가있는 경우에 유용합니다 . 예를 들어, 내 사용자 지정 동등성 비교 함수를 사용하는 해시 테이블을 인스턴스화한다고 가정합니다. 다음과 같이 말할 수 있기를 바랍니다.

typedef std::unordered_map<
  std::string,
  std::string,
  std::hash<std::string>,
  decltype([](const std::string& s1, const std::string& s2)->bool 
    { /* Custom implementation of equal_to */ })
  > map_type;

그러나 나는 이것을 GCC 4.4 및 4.6에서 테스트했지만 람다 식으로 만든 익명 유형에 기본 생성자가 없기 때문에 작동하지 않습니다. (나는에서 비슷한 문제를 회상합니다 boost::bind.) 표준 초안이 이것을 허용하지 않는 이유가 있습니까, 아니면 내가 잘못하고 허용되었지만 GCC가 구현에서 뒤쳐져 있습니까?


다음과 같이 할 수 있는지 묻습니다.

Foo<decltype([]()->void { })> foo;

람다 식은 평가되지 않은 컨텍스트 (예 : decltypeand 등)에 표시되지 않으므로 할 수 없습니다 sizeof. C ++ 0x FDIS, 5.1.2 [expr.prim.lambda] p2

람다 식의 평가는 prvalue 임시 (12.2)를 생성합니다. 이 임시를 클로저 객체라고합니다. 람다 표현식은 평가되지 않은 피연산자 (5 절)에 나타나지 않습니다 . [참고 : 클로저 객체는 함수 객체 (20.8)처럼 동작합니다 .—end note] (강조 내)

먼저 특정 람다를 만든 다음 decltype을 사용해야합니다.

auto my_comp = [](const std::string& left, const std::string& right) -> bool {
  // whatever
}

typedef std::unordered_map<
  std::string,
  std::string,
  std::hash<std::string>,
  decltype(my_comp)
  > map_type;

람다에서 파생 된 각 클로저 객체는 완전히 다른 유형을 가질 수 있기 때문에 결국 익명 함수 와 같습니다 .


@Xeo가 이유를 알려 주었으므로 해결 방법을 알려 드리겠습니다.

종종 클로저의 이름을 지정하지 않으려는 경우가 있습니다.이 경우 std::function유형 인을 사용할 수 있습니다 .

typedef std::unordered_map<
  std::string,
  std::string,
  std::hash<std::string>,
  std::function<bool(std::string const&, std::string const&)>
  > map_type;

함수의 시그니처를 정확히 캡처하고 더 이상 캡처하지 않습니다.

그런 다음지도를 만들 때 간단히 람다를 작성할 수 있습니다.

함께주의 unordered_map는 평등 비교를 변경하는 경우, 당신은 더 나은 동작을 일치하도록 해시를 변경할 것입니다. 동일하게 비교되는 객체는 동일한 해시를 갖습니다.


상태가 유형에 포함되어 있지 않기 때문에 클로저로는이를 수행 할 수 없습니다.

람다가 상태 비 저장 (캡처 없음)이면 괜찮습니다. 이 경우 람다는 람다 형식 대신 템플릿 인수로 사용할 수있는 일반 함수 포인터로 감쇠됩니다.

gcc는 그것을 좋아하지 않습니다. http://ideone.com/bHM3n


와 같은 런타임 추상 유형을 사용하거나 std::function유형을 지역 변수 또는 템플릿 클래스의 일부로 만들어야합니다.

참고URL : https://stackoverflow.com/questions/5849059/lambda-expressions-as-class-template-parameters

반응형