سؤال

ما هو الخطأ مع البرنامج قليلا بعد أن يمر كائن وظيفة؟

#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، لا يمكنك نسخ عموما، لأن المستخدم قد مرت على وظيفة. نسخها ثم ستحاول يعلن محليا وظيفة بدلا من مؤشر الدالة المحلي. ومع ذلك، وقبول كل قيمة سيقبل مؤشر الدالة بدلا عندما تم تمرير وظيفة، والتي يمكن بأمان يتم نسخها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top