سؤال

ما هو الخطأ في ما يلي مقتطف ?

#include <tr1/functional>
#include <functional>
#include <iostream>

using namespace std::tr1::placeholders;

struct abc
{
    typedef void result_type;

    void hello(int)
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    void hello(int) const
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    abc()
    {}
};

int
main(int argc, char *argv[])
{
    const abc x;
    int a = 1;

    std::tr1::bind(&abc::hello, x , _1)(a);
    return 0;
}

محاولة تجميع مع g++-4.3 ، يبدو أن السيرة الذاتية-تصفيات طاقتها وظائف تخلط كل tr1::mem_fn<> و tr1::bind<> ويخرج الخطأ التالية:

no matching function for call to ‘bind(<unresolved overloaded function type>,...

بدلا المقتطف التالي برمجيا ولكن يبدو أن كسر const-صحة:

struct abc
{
    typedef void result_type;

    void operator()(int)
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    void operator()(int) const
    { std::cout << __PRETTY_FUNCTION__ << std::endl; }

    abc()
    {}
};

...

    const abc x;
    int a = 1;
    std::tr1::bind( x , _1)(a);

أي فكرة ؟

هل كانت مفيدة؟

المحلول

البحث يتم في وقت constness من this ليست معروفة.عليك أن تعطي تلميحا عن طريق الصب.جرب هذا:

typedef void (abc::*fptr)(int) const; // or remove const
std::tr1::bind((fptr)&abc::hello, x , _1)(a);

قد تلاحظ أيضا هنا أن إزالة const لا يزال يعمل.هذا هو لأنه يجب أن يمر x من قبل مؤشر (لأن الحجة الأولى إلى C++ الأعضاء الدالة الضمنية this المعلمة هو دائما مؤشر).جرب هذا بدلا من ذلك:

typedef void (abc::*fptr)(int) const; // won't compile without const (good!)
std::tr1::bind((fptr)&abc::hello, &x , _1)(a);

كما اكتشفت أثناء ضمن التعليقات أدناه ، إذا قمت بحذف & وأنت أصلا لم لتكون عابرة x من حيث القيمة, التي هي عادة ليست ما تريد (على الرغم من أنه يجعل عملي يذكر الفرق في المثال).هذا يبدو في الواقع مثل مؤسفة شرك عن bind.

نصائح أخرى

هذا السؤال تمت الإجابة, ولكن أجد أفضل طريقة لتحديد الزائد مع ربط ذلك هو تحديد ذلك على القالب:

std::tr1::bind<void(foo::*)(int)>(&foo::bar);

هذا الأسلوب هو مجرد صريحة ، ولكن أقصر من الصب (مع static_cast على أي حال.لكنه أنظف من ج-cast, وهو نفس الطول.

كما اقترح جون مشاكل نشأت في تلك المقتطفات التالية:

  1. عند تمرير الأعضاء-وظيفة-المؤشر من الضروري تحديد التوقيع (إذا طاقتها)
  2. bind() يتم تمرير الحجج من حيث القيمة.

أول حل المشكلة قبل الصب الأعضاء مؤشر وظيفة توفير ربط:

    std::tr1::bind(static_cast< void(abc::*)(int) const >(&abc::hello), x, _1)(a);

الثانية يمكن حلها عن طريق تمرير للاستدعاء كائن من العنوان (كما اقترح جون) ، أو عن طريق TR1 reference_wrapper<> -- وإلا فإنه سيتم تمريرها حسب القيمة ، مما يجعل const-صحة كسر هلوسة.

نظرا x للاستدعاء وجوه:

std::tr1::bind( std::tr1::ref(x) , _1)(a);

bind() إلى الأمام a السليم operator() وفقا x constness.

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