تمرير الكائن وظيفة: خطأ
-
22-08-2019 - |
سؤال
ما هو الخطأ مع البرنامج قليلا بعد أن يمر كائن وظيفة؟
#include <iostream>
#include <functional>
void foo(const std::unary_function<const std::string&, void>& fct) {
const std::string str = "test";
fct(str); // error
}
class MyFct : public std::unary_function<const std::string&, void> {
public:
void operator()(const std::string& str) const {
std::cout << str << std::endl;
}
};
int main(int argc, char** argv){
MyFct f;
foo(f);
return 0;
}
وأنا الحصول على الخطأ التالي في خط 6:
no match for call to
`(const std::unary_function<const std::string&, void>) (const std::string&)'
المحلول
وهناك خطأ شائع. unary_function
وbinary_function
هما فقط البنيات التي تضيف typedefs
argument_type
result_type
وعلى التوالي
first_argument_type
second_argument_type
result_type
وليس أكثر من ذلك. هم لراحة المبدعين من أنواع الكائنات وظيفة، لذلك لم يكن لديهم للقيام بهذه أنفسهم. لكنها لا تتصرف متعدد الأشكال. ما تريد هي وظيفة المجمع الكائن. boost::function
يتبادر إلى الذهن:
void foo(boost::function<void(const std::string&)> const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
وأو جعله نموذجا
template<typename FunctionObject>
void foo(FunctionObject const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
ويمكنك أن تأخذ من حيث القيمة ومن ثم العودة إلى نسخة من foo
إذا استخدامه لتطبيقه على بعض التسلسل. التي من شأنها أن تسمح للجسم وظيفة لتحديث بعض المتغيرات دولة من بين أعضائها. for_each
مثال أن يفعل مثل ذلك. عموما، على أية حال، أود أن قبولها من حيث القيمة لأنها عادة ما تكون صغيرة ونسخها تسمح بقدر أكبر من المرونة. لذلك أفعل
template<typename FunctionObject>
void foo(FunctionObject fct) {
const std::string str = "test";
fct(str); // no error anymore
}
وسوف تكون بعد ذلك قادرة على أخذ نسخة من إقليم العاصمة الاتحادية وحفظه في مكان ما، ومشغل fct
ل() يمكن أن يكون غير CONST وتحديث بعض أعضاء (والذي هو جزء من بيت القصيد من operator()
). تذكر إذا كنت تأخذ كائن وظيفة بالرجوع CONST، لا يمكنك نسخ عموما، لأن المستخدم قد مرت على وظيفة. نسخها ثم ستحاول يعلن محليا وظيفة بدلا من مؤشر الدالة المحلي. ومع ذلك، وقبول كل قيمة سيقبل مؤشر الدالة بدلا عندما تم تمرير وظيفة، والتي يمكن بأمان يتم نسخها.