سؤال

ما هو سبب الأقواس الثانية <> في قالب الوظيفة التالية:

template<> void doh::operator()<>(int i)

هذا جاء في حتى سؤال حيث اقترح أن هناك أقواس مفقودة بعد operator(), ومع ذلك لم أستطع العثور على التفسير.

أفهم معنى إذا كان تخصصا من النوع (التخصص الكامل) للنموذج:

template< typename A > struct AA {};
template<> struct AA<int> {};         // hope this is correct, specialize for int

ومع ذلك بالنسبة لقوالب الوظيفة:

template< typename A > void f( A );
template< typename A > void f( A* ); // overload of the above for pointers
template<> void f<int>(int);         // full specialization for int

أين يلتزم هذا في هذا السينار؟:

template<> void doh::operator()<>(bool b) {}

مثال رمز يبدو أنه يعمل ولا يعطي أي تحذيرات / خطأ (GCC 3.3.3 المستخدمة):

#include <iostream>
using namespace std;

struct doh
{
    void operator()(bool b)
    {
        cout << "operator()(bool b)" << endl;
    }

    template< typename T > void operator()(T t)
    {
        cout << "template <typename T> void operator()(T t)" << endl;
    }
};
// note can't specialize inline, have to declare outside of the class body
template<> void doh::operator()(int i)
{
    cout << "template <> void operator()(int i)" << endl;
}
template<> void doh::operator()(bool b)
{
    cout << "template <> void operator()(bool b)" << endl;
}

int main()
{
    doh d;
    int i;
    bool b;
    d(b);
    d(i);
}

انتاج:

operator()(bool b)
template <> void operator()(int i)
هل كانت مفيدة؟

المحلول

لقد بحثت عنه، ووجدت أنه تم تحديده بمقدار 14.5.2/2:

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

ويوفر مثالا:

template <class T> struct A {
    void f(int);
    template <class T2> void f(T2);
};

template <> void A<int>::f(int) { } // non-template member
template <> template <> void A<int>::f<>(int) { } // template member

int main()
{
    A<char> ac;
    ac.f(1); //non-template
    ac.f(’c’); //template
    ac.f<>(1); //template
}

لاحظ أنه في المصطلحات القياسية، specialization يشير إلى الوظيفة التي تكتبها باستخدام تخصص صريح وإندنا إلى الوظيفة التي تم إنشاؤها باستخدام مثيل، وفي هذه الحالة علينا أن نفعل مع تخصص تم إنشاؤها. specialization لا يشير فقط إلى الوظائف التي تنشئها باستخدام قالب متخصص بشكل صريح، والتي غالبا ما تستخدمها فقط.

الخلاصة: GCC يحصل على خطأ. COMEAU، التي اختبرت أيضا التعليمات البرمجية، تحصل عليها بشكل صحيح وقضايا تشخيص:

"ComeauTest.c", الخط 16: خطأ: "void doh::operator()(bool)" ليس كيانا يمكن التخصصي بشكل صريح template<> void doh::operator()(bool i)

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

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