لماذا لا يحدد برنامج التحويل البرمجي التحميل الزائد للوظيفة في المثال التالي؟

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

سؤال

بالنظر إلى قوالب الوظيفة التالية:

#include <vector>
#include <utility>

struct Base { };
struct Derived : Base { };

// #1
template <typename T1, typename T2>
void f(const T1& a, const T2& b)
{
};

// #2
template <typename T1, typename T2>
void f(const std::vector<std::pair<T1, T2> >& v, Base* p)
{
};

لماذا يستدعي الرمز التالي دائمًا الحمل الزائد رقم 1 بدلاً من التحميل الزائد رقم 2؟

int main()
{
    std::vector<std::pair<int, int> > v;
    Derived derived;

    f(100, 200);  // clearly calls overload #1
    f(v, &derived);         // always calls overload #1

    return 0;
}

بالنظر إلى أن المعلمة الثانية من f هو نوع مشتق من Base, ، كنت آمل أن يختار المترجم الحمل الزائد رقم 2 لأنه تطابق أفضل من النوع العام في الحمل الزائد رقم 1.

هل هناك أي تقنيات يمكنني استخدامها لإعادة كتابة هذه الوظائف حتى يتمكن المستخدم من كتابة التعليمات البرمجية كما هو معروض في main الوظيفة (أي ، الاستفادة من ترجمة التحويل البرمجي لأنواع الحجج)؟

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

المحلول

يمكنك إما القيام بذلك:

f(v, static_cast<Base*>(&derived));

أو استخدم sfinae لإزالة الوظيفة الأولى كمرشح اختيار:

// Install boost library and add these headers:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

// #1 - change it to look like this (note the keyword void changed positions)
template <typename T1, typename T2>
typename boost::disable_if<
   typename boost::is_convertible<T2, Base*>, void>::type
f(const T1& a, const T2& b)
{
};

// #2 - this one can stay the same
template <typename T1, typename T2>
void f(const std::vector<std::pair<T1, T2> >& v, Base* p)
{
};

نصائح أخرى

بالنظر إلى أن المعلمة الثانية من F هي نوع مشتق من القاعدة

إنه قابل للتحويل إلى هذا ، لكنه مشتق*. لا تتطلب وظيفة القالب الأول أي تحويلات ، والثاني يتطلب واحدة ، وبالتالي تختار الأول.

هذا يختار الثاني:

f(v, static_cast<Base*>(&derived));

في ملحوظة جانبية، main يعود int.

بجانب الموضوعات الواضحة حول Koenig Lookup يتم تنفيذ ذلك بشكل جيد أو أقل من قبل المُسارين (خاصةً الأكبر سناً يمثل مشكلة كبيرة) ، هناك بعض المزالق فيما يتعلق تخصص قالب.

يتطلب التخصص الأنواع لتتطابق تمامًا (غير متأكد من كيفية تعريف STD هذا ، ولكن من تجربتي [GCC ، MSVC] لن يتم مطابقة فئة مشتقة). إذا قمت بإضافة ممثلين قبيح إلى قاعدة*، فيجب أن تعمل كما تنوي ، إضافة اختياريًا تخصصًا آخر للمشتقة ...

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