c++ - قرار الزائد للوظائف الموروثة



templates inheritance (1)

إنه أمر بسيط عندما تكتشفه: المشغل غير مؤهل ، في حين أن عامل lambda هو (ما لم تحدد lambda على أنه mutable ). وبالتالي ، فهي تطابق أفضل Poc غير الثابتة لـ Poc .

فقط أضف const مفقود:

auto operator() (Ts...) const

أريد أن يكون لدي هيكل يأخذ عددًا تعسفيًا من lambdas ويعمل كنقطة اتصال مركزية لجميع مشغلي مكالماتهم.

إذا تم استدعاء مشغل الاتصال بقائمة وسيطة لا تتطابق مع أي من lambdas المقدمة عند الإنشاء ، فيجب استدعاء مشغل اتصال افتراضي.

اعتقدت أن الكود التالي سينجز هذا بالضبط. يتم رفع "مشغل الاتصال" لكل لامدا إلى فئة Poc عبر using .

template <typename ...Lambdas>
struct Poc : Lambdas...
{
    using Lambdas::operator() ...; // Lift the lambda operators into the class

    template <typename ...Ts>
    auto operator() (Ts...)
    {
        std::cout << "general call" << std::endl;
    }
};

// Deduction guide
template <typename ...Ts>
Poc(Ts... ts)->Poc<Ts...>;

int main()
{
    auto l_int = [](int) {std::cout << "int" << std::endl; };

    Poc poc{l_int};
    poc(1);//calls the default operator. why?

    return 0;
}

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

حسب فهمي ، فإن مشغلي مكالمة lambda ومشغلي مكالمات (افتراضي) موجودون في نفس النطاق. لذلك ، يجب أن يتم البحث عن دقة التحميل الزائد. نظرًا لأن المشغل lamdba أكثر تحديدًا من المشغل الافتراضي العام ، فيجب اختياره.

يبدو أن الأمر ليس كذلك. لماذا هذا؟

لقد اختبرت في Microsoft Visual C ++ و Clang و GCC (جميعها في أحدث إصداراتها).

تصحيح:





overloading