متعددة الأشكال functors في std::for_each
-
03-07-2019 - |
سؤال
أحاول استخدام الخوارزمية الخاصة بلبنان for_each دون تكاثر القوالب في جميع أنحاء قانون بلدي.الأمراض المنقولة جنسيا::for_each يريد مثيل MyFunctor الدرجة من حيث القيمة ، ولكن لا يمكن أن منذ مجردة.لقد خلق functor محول الدرجة التي يمر مؤشر حولها ثم derefernces ذلك عند الاقتضاء.
سؤالي:
هل المحكمة الخاصة بلبنان أو دفعة بالفعل مثل هذا محول الصف ؟ أنا لا أريد أن لديك لإعادة اختراع العجلة!
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 :: المرجع قد تساعدك هنا --- التي من المفترض أن يكون المجمع مرجعية بحيث يمكنك تمرير الكائنات العادية بالرجوع إلى ربط أو الأشياء وظيفة (حتى تلك مجردة) بالرجوع إلى خوارزميات القياسية.
// 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 دعم <م> MAY م> رفض تمرير إشارة إلى نوع مجردة ... لذلك هذا الرمز قد لا ترجمة حتى تحصل 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 ) );
ومع المزيد من الحجج، فإنه يصبح أكثر قابلية للقراءة لخلق حلقة نفسك، أو إنشاء functor مخصص يحتوي المتغيرات عضو CONST تمثل الحجج.
لماذا لا تستخدم BOOST_FOREACH؟
يبدو أنك يمكن أن تستفيد من دفعة::وظيفة.
إذا كنت أتذكر بشكل صحيح إنه رأس فقط مكتبة أيضا ، لذلك فإنه من السهل أن تحصل عليه الذهاب معها.
وماذا عن نسيان كل التفاف مؤشر functor، وبدلا من استخدام
bind(functor_pointer,mem_fun1(&MyFunctor::operator());
كما functor؟ بهذه الطريقة، لم يكن لديك ما يدعو للقلق حول إدارة النسخة في أي وسيلة أو شكل.
وبناء على الجواب @ xtofl، لأن مجموعة تحتوي على كثافة العمليات وليس "هذا" مؤشرات، وأعتقد أن التعويذة الصحيح
class MyClass
{
virtual void process(int number) = 0;
};
MyClass *instance = ...;
for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );
والفرق الوحيد مقابل @ xtofl ومتاحة binder1st بدلا من binder2nd. binder2nd يسمح لك بالمرور تيه نفس العدد لمختلف "هذا" مؤشرات. binder1st يسمح لك بالمرور أرقام مختلفة ل"هذا" مؤشر واحد.