std :: for_each의 다형성 기능
-
03-07-2019 - |
문제
코드 전체에서 템플릿을 증식하지 않고 STL 알고리즘 for_each를 사용하려고합니다. std :: for_each는 값으로 myfunctor 클래스를 인스턴스화하기를 원하지만 추상적 인 이후로는 할 수 없습니다. Functor Adapter 클래스를 만들어 포인터를 통과 한 다음 적절할 때는 DereFernces를 만들었습니다.
내 질문:
STL 또는 부스트에는 이미 그러한 어댑터 클래스가 있습니까? 나는 바퀴를 재창조하고 싶지 않다!
struct MyFunctor {
virtual ~MyFunctor() {}
virtual void operator()(int a) = 0;
}
namespace {
template<typename FunctorType, typename OperandType> struct
FunctorAdapter
{
FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
void operator()(OperandType& subject)
{
(*mFunctor)(subject);
}
FunctorType* mFunctor;
}; }
void applyToAll(MyFunctor &f) {
FunctorHelper<MyFunctor, int> tmp(&f);
std::for_each(myvector.begin(), myvector.end(), tmp); }
건배,
데이브
해결책
TR1 :: REF가 여기에서 도움이 될 수 있습니다.
// requires TR1 support from your compiler / standard library implementation
#include <functional>
void applyToAll(MyFunctor &f) {
std::for_each(
myvector.begin(),
myvector.end(),
std::tr1::ref(f)
);
}
그러나 Decltype 지원이없는 컴파일러는 이에 유의하십시오 5월 추상 유형에 대한 참조를 전달하는 것을 거부하십시오 ...이 코드는 C ++ 0X 지원을받을 때까지 컴파일되지 않을 수 있습니다.
다른 팁
기능 어댑터 (및 심)를 사용할 수 있습니다. functional
.
#include <functional>
using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );
컨테이너에 포인터 투 객체가 포함 된 경우 사용하십시오 mem_fun_ptr
, 그렇지 않으면 사용합니다 mem_fun
. 이 옆에는 1 인수를 취하는 멤버 기능을위한 포장지가 있습니다. mem_fun1_ptr
그리고 mem_fun1
.
@evan : 실제로, 각 객체에 대해 동일한 인수로 멤버 함수를 호출 할 수 있습니다. 첫 번째 논쟁 mem_fun1
포장지는 다음과 같습니다 this
포인터, 두 번째는 멤버 함수 인수입니다.
for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );
더 많은 인수를 사용하면 루프 직접 작성하거나 인수를 나타내는 Const 멤버 변수가있는 사용자 정의 펀치를 만드는 것이 더 읽기 쉬워집니다.
roost_foreach를 사용하지 않는 이유는 무엇입니까?
당신이 혜택을 누릴 수있는 것처럼 들립니다 부스트 :: 기능.
내가 올바르게 기억한다면 그것은 헤더 전용 라이브러리이기 때문에 쉽게 갈 수 있습니다.
Functor 포인터의 모든 포장을 잊어 버리고 대신 사용하는 것은 어떻습니까?bind(functor_pointer,mem_fun1(&MyFunctor::operator());
Functor로? 그렇게하면 사본을 어떤 방식 으로든 관리하는 것에 대해 걱정할 필요가 없습니다.
@xtofl의 답변을 바탕으로 배열에는 "이"포인터가 아닌 int가 포함되어 있기 때문에 올바른 주문은
class MyClass
{
virtual void process(int number) = 0;
};
MyClass *instance = ...;
for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );
@XTOFL의 유일한 차이점은 binder2nd보다는 binder1st입니다. Binder2nd를 사용하면 동일한 숫자를 다양한 "이"포인터로 전달할 수 있습니다. Binder1st를 사용하면 다양한 숫자를 하나의 "이"포인터로 전달할 수 있습니다.