سؤال

أواجه مشكلة في الاعتبار mem_fun_ref. وبعد يجب أن أعترف، عادة ما أستخدم functors لهذا النوع من الأشياء، حيث يمكن إبزيتها للسرعة والربح. ومع ذلك، فإن هذا الرمز لن يكون عنق الزجاجة ولذا أردت أن أجرب هذا الشيء.

هنا مثال على ما أريد القيام به. أعرف أن هناك طرق أخرى للقيام بذلك. لا أريد استخدام copy, ، لا أريد استخدام وظائف عضو المدى، لا أريد استخدام back_inserter. وبعد أنا تريد خصيصا استخدام mem_fun_ref. وبعد هذا هو مجرد مثال بسيط، الحالة الحقيقية أكثر تعقيدا. ومع ذلك، أنا حقا لا أعرف لماذا هذا خطأ، لكنني لست على دراية mem_fun_ref أو mem_fun.

إليك ما أريد عمله:

#include <list>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
    list<int> a;
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);
    vector<int> b;

    // should work like magic!
    for_each(a.begin(), a.end(), bind1st(mem_fun_ref(&vector<int>::push_back), b));
}

لكنني أحصل على 3 أخطاء:

1>c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(281) : error C2529: '_Right' : reference to reference is illegal
1>c:\program files\microsoft visual studio 9.0\vc\include\functional(282) : error C2535: 'void std::binder1st<_Fn2>::operator ()(const int &(&)) const' : member function already defined or declared
1>        with
1>        [
1>            _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1>        ]
1>        c:\program files\microsoft visual studio 9.0\vc\include\functional(276) : see declaration of 'std::binder1st<_Fn2>::operator ()'
1>        with
1>        [
1>            _Fn2=std::mem_fun1_ref_t<void,std::vector<int>,const int &>
1>        ]

reference to reference is illegal يجعلني أعتقد أن الوظيفة تحتاج إلى اتخاذ معلمة حسب القيمة. ولكن بالطبع، هذا غير ممكن للتغيير في vector, ، وليس من الممكن تغييره في التعليمات البرمجية أيضا. هل هناك تغيير بسيط للحصول على هذا للعمل؟ أحتاج إلى حل واحد بطانة 1.

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

المحلول

مجرد استخدام bind. وبعد ال mem_fun الإصدارات صعبة للغاية.

for_each(a.begin(), a.end(),
  boost::bind(&vector<int>::push_back, boost::ref(b), _1));

طريقة أخرى لا تتطلب استخدام ref هو تمرير مؤشر إلى ناقل المعدل:

for_each(a.begin(), a.end(),
  boost::bind(&vector<int>::push_back, &b, _1));

نصائح أخرى

تم شرح هذه المشكلة في "أسلوب C ++ استثنائي +" بواسطة Herb Sutter، صفحة 28-30. ربما لا يمكن للمرء أن يخلق مؤشر بأمان vector<int>::push_back الطريقة كما يحتاج المرء أن تتأكد من التوقيع الدقيق لوظيفة العضو، مما قد لا يكون واضحا حتى vector<int>::push_back في المكتبة القياسية. هذا لأنه (في المكتبة القياسية):

  1. قد يتم استبدال توقيع وظيفة الأعضاء مع المعلمات الافتراضية ب "توقيعات وظيفة عضوا أو أكثر مع سلوك مكافئ.
  2. قد يحتوي توقيع وظيفة الأعضاء على معلمات افتراضية إضافية.

في النهاية، نصح عشبة سوتر ذلك

  1. استخدم mem_fun، ليس فقط مع المكتبة القياسية
  2. استخدام المؤشرات إلى وظائف الأعضاء، ليس فقط مع المكتبة القياسية

أعلم أنك قلت أنك لا تريد استخدامها back_inserter, ربما لأنك قد قدمت رمز مثال مبسطة فقط.

لأي شخص آخر يتساءل كيف نفعل بالضبط ما تحاول القيام به، وسعدت باستخدامه، واستخدام back_inserter:

std::copy(a.begin(), a.end(), std::back_inserter(b));

ومع ذلك، هناك دائما other_mem_fun, ، التي طهيها قبل أن أعرفها عن التعزيز. قد يصلح هذا.

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