ز ++ ترفض بلدي functor بسيط مع "المتوقع نوع، وحصلت" XYZ "

StackOverflow https://stackoverflow.com/questions/825015

  •  05-07-2019
  •  | 
  •  

سؤال

ولقد لعب حولها مع [فونكتورس] في C ++. على وجه الخصوص، لقد حصلت على ناقلات أزواج أود لترتيب النتائج بحسب العنصر الأول من الزوج. لقد بدأت كتابة functor متخصص تماما (أي شيء من هذا القبيل "منطقي MyLessThan (MyPair وLHS، MyPair ويمين)"). ثم، لمجرد هذا النوع من الاشياء هي مثيرة للاهتمام، وأنا أردت أن يحاول كتابة عامة "تطبيق F إلى العناصر الأولى من هذا الزوج" functor. كتبت أدناه، ولكن ز ++ لا ترغب في ذلك. أحصل على:

والخطأ: عدم تطابق نوع / قيمة في حجة 2 في قائمة المعلمة القالب ل 'قالب البنية Pair1stFunc2 " خطأ: من المتوقع نوع، وحصلت 'أقل'

#include <algorithm>
#include <functional>
#include <utility>
#include <vector>

template <class P, class F>
struct Pair1stFunc2
{
    typename F::result_type operator()(P &lhs, P &rhs) const
    { return F(lhs.first, rhs.first); }

    typename F::result_type operator()(const P &lhs, const P &rhs) const
    { return F(lhs.first, rhs.first); }
};

typedef std::pair<int,int> MyPair;
typedef std::vector<MyPair> MyPairList;

MyPairList pairs;

void foo(void)
{
    std::sort(pairs.begin(),
              pairs.end(),
              Pair1stFunc2<MyPair, std::less>());
}

ويمكن لأي شخص أن يلقي أي ضوء على ما أفعله خطأ هنا؟ أعرف أن هذا هو سبيل المثال كما الاصطناعي قليلا، ولكن أود أن أعرف ما يحدث، إلا إذا كان لتحسين لغتي STL-فو.

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

المحلول

وتحتاج للتخصص الأمراض المنقولة جنسيا :: أقل مع المقارنة اكتب الذي تستخدمه.

Pair1stFunc2<MyPair, std::less<int> >()

وسوف تفعل خدعة. داخل المشغل الخاص بك () ستحتاج أيضا إلى مثيل كائن من نوع المقارنة، لأنك لا يمكن أن مجرد دعوة الطبقة مباشرة. مثلا تغيير

return F(lhs.first, rhs.first);

إلى

F func;
return func(lhs.first, rhs.first);

هل يمكن أيضا نقل التخصص في functor، كما تقترح إجابة أخرى.

نصائح أخرى

لتوسيع على إجابة dirkgently، وهنا مثال على ما يمكن أن تعمل كما كنت تنوي:

template <typename T, template <typename> class F>
struct Pair1stFunc2
{
    template <typename P>
    typename F<T>::result_type operator()(P &lhs, P &rhs) const
    { F<T> f; return f(lhs.first, rhs.first); }

    template <typename P>
    typename F<T>::result_type operator()(const P &lhs, const P &rhs) const
    { F<T> f; return f(lhs.first, rhs.first); }
};

void foo(void)
{
    std::sort(pairs.begin(),
              pairs.end(),
              Pair1stFunc2<int, std::less>());
}

لاحظ أن يعمل، ولكنه قد لا يكون بالضبط ما كان في الحسبان.

لاحظ أن std::less هو في حد ذاته قالب ولم تقم بتحديد المعلمة قالب قالب عندما كنت اسميها من foo() مع وظيفة sort المفضل هنا less هو نوع غير مكتملة، وبالتالي المشكلة.

وعلى غرار unwesen. ولكنك لا تحتاج إلى استخدام القوالب القالب.

#include <algorithm>
#include <functional>
#include <memory>
#include <vector>

typedef std::pair<int,int> MyPair;
typedef std::vector<MyPair> MyPairList;
MyPairList pairs;


// Same as original.
template <typename T,typename F>
struct Pair1stFunc2
{
    template <typename P>
    typename F::result_type operator()(P &lhs, P &rhs) const
    { F f;  // Just need to create an anstance of the functor to use.
      return f(lhs.first, rhs.first); }

    template <typename P>
    typename F::result_type operator()(const P &lhs, const P &rhs) const
    { F f;  // Just need to create an anstance of the functor to use.
      return f(lhs.first, rhs.first); }
};


void foo(void)
{
    std::sort(pairs.begin(),
              pairs.end(),
              Pair1stFunc2<int, std::less<int> >()); // initialize the version of less
}

وأبسط حل سيكون لدولة ما تريد كحجة، وهي وظيفة مع توقيع مناسب:

template<typename P, bool (*F)(P,P)> struct Pair1stFunc2 { ... }

في هذه الحالة، ويمر قالب وظيفة كما الوسيطة الثانية سوف تسبب قرار الزائد الذي يتعين القيام به على ذلك مع P، P كأنواع حجة. يعمل هذا لأن قمت بنقل قرار الزائد من struct Pair1stFunc2::operator()

وتحتاج أيضا إمكانية تمرير في functor ، ولكن هذه لا تحتاج لتمريرها كوسيطة نوع القالب ثم تم إنشاؤها داخل المشغل ():

typename F::result_type operator()(const P &lhs, const P &rhs) const
{ return F()(lhs.first, rhs.first); }

وهنا، F هو نوع functor وF () مثيل من هذه functor.

وبالفعل يغطي الحالة الثالثة في وقت سابق، القالب functor. الأمراض المنقولة جنسيا :: أقل مثل هذا القالب. في هذه الحالة، تحتاج إلى حجة قالب قالب.

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