여기에서 (endo) functor는 객체를 가져 와서 같은 유형의 다른 객체에서 변형 할 수있는 것입니다. 가장 간단한 functor의 예는 ID입니다.endofunctor 개념 또는 인터페이스
struct Identity {
template <typename T>
T Apply(T x) {
return x
}
};
일반 Functor를 식별하는 "Functor type"이 필요합니다.
struct Functor {
template <typename T>
virtual T Apply(T x) = 0;
};
이 접근 방식의 해결 못하는 문제가 서식한다는 것입니다 : 내 마음에 온
class Sum {
public:
Sum(Functor* f, Functor* g) :
f_(f),
g_(g) {}
template <typename T>
T Apply(T x) { return f_->Apply(x) + g_->Apply(x); }
private
Functor* f_;
Functor* g_;
};
첫 번째 아이디어 물론 가상 클래스를 사용한다 : 내가 뭘하고 싶은처럼 쓰기 코드는 가상 일 수는 없다.
그런 다음 C++ 개념을 사용해 보았습니다. 그러나 Specifying a concept for a type that has a member function template using Concepts Lite과 C++ Concepts: Can I define a concept that is itself a template?에 명시된 바와 같이 "템플릿 개념"은 사용할 수 없습니다.
마지막으로 나는 How to achieve "virtual template function" in C++ 우연히 발견하고, 따라서 나는 다음과 같은 가능한 구현 해낸 :이 컴파일하더라도
struct Functor {
template <typename T>
T Apply(const T& x); // No more virtual!!!
};
// ... Identity and Sum declarations properly inheriting from Functor ...
template <typename T>
T Functor::Apply(T x) {
if (Identity* specialized =
dynamic_cast<Identity*>(this)) {
return specialized->Apply(x);
} else if (const Sum* specialized =
dynamic_cast<const Sum*>(this)) {
return specialized->Apply(x);
} else ...
}
, 그것은 최선의 해결책이 아니다. 주요 문제는 성능 및 코드 반복입니다. 성능 문제는 Functor에서 Apply를 호출 할 때마다 Functor :: Apply 내부의 긴 if 절이 해결되어야한다는 사실에서 기인합니다. Functor가 깊게 중첩 될 수 있으므로 큰 문제입니다 (Apply를 호출하면 Functor :: Apply가 여러 번 호출 될 수 있음). "코드 반복"문제는 새로운 Functor를 정의 할 때마다 Functor :: Modify를 수정해야 할 때마다 새로운 if 절을 추가 할 때마다 분명합니다.
여기서 내가 묻는 것은 합계와 같은 클래스를 만들 수있는 Functor 인터페이스/개념을 정의하는 적절한 (더 명확한) 방법이 있는지 여부입니다. C++ 개념 및 무거운 템플릿 메타 프로그래밍이 허용됩니다.
p.s. 모든 코드 스 니펫은 가능한 한 간단하게 유지됩니다. 구조체 대신 클래스를 사용하거나 const 식별자를 추가하거나 고유 한 포인터를 사용하라는 제안은 피하십시오.이 질문의 요지는 아닙니다.
저는 std :: function을 펑터 (functor)로 사용하려고합니다. –
"C++ 1z"에는 개념이 없습니다. –
'T'유형이 모든 기능에 대해 동일하면 가상 기능을 사용하려면 기능 수준 대신 클래스 수준에서 이동할 수 있습니다. 그러나 최상의 솔루션은 아닙니다. 이미 제안했듯이, 나는'std :: function'이 도움이 될 수 있는지 살펴봄으로써 시작할 것입니다. – Phil1970