سؤال

في C ++، من المفترض أن يتصرف تخصص قالب الوظائف تماما مثل وظيفة طبيعية. هل هذا يعني أنني أستطيع أن أجعل واحدة افتراضية واحدة؟

علي سبيل المثال:

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

struct B : A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

int main(int argc, char* argv[])
{
    B b;
    A& a = b;
    a.f<int>();
}

Visual Studio 2005. يعطيني الخطأ التالي:

خطأ فادح C1001: حدث خطأ داخلي في التحويل البرمجي.

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

المحلول

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

Comeau C / C ++ 4.3.10.1 (6 أكتوبر 2008 11:28:09) بالنسبة إلى Online_evaluation_beta2 حقوق الطبع والنشر 1988-2008 Comeau Computing. كل الحقوق محفوظة. الوضع: أخطاء صارمة C ++ C ++ 0x_extensions

"comeautest.c"، الخط 3: خطأ: "الظاهري" غير مسموح به في قالب إعلان قالب وظيفة Virtual Void F ()؛ ^

"COMEAUTEST.C"، خط 10: خطأ: "الظاهري" غير مسموح به في قالب إعلان قالب وظيفة Virtual Void F ()؛ ^

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

إذا كان ما تريده هو وظيفة TEMPLATETED على إحدى وسيطاتها وإصدار واحد محدد بأنها افتراضية (لاحظ جزء الوسيطة) يمكنك القيام بذلك:

class Base
{
public:
   template <typename T> void f( T a ) {}
   virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
   virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
   Derived d;
   Base& b = d;
   b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}

إذا كنت تريد هذا المعمم لأي نوع، فأنت خارج الحظ. النظر في نوع آخر من الوفود بدلا من تعدد الأشكال (تجميع + يمكن أن يكون وفد حل). المزيد من المعلومات حول المشكلة في متناول اليد سوف تساعد في تحديد حل.

نصائح أخرى

وفق http://www.kuzbass.ru:8086/docs/isocpp/template.html. ISO / IEC 14882: 1998:

-3- لا يكون قالب وظيفة العضو الظاهري.

مثال:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};

كما لاحظ الآخرون، هذا ليس قانونا قانونيا لأن قالب وظيفة العضو لا يمكن الإعلان عنه virtual.

ومع ذلك حتى Visual Studio 2012 Shokes على هذا:C++ internal compiler error on Visual Studio 2012 انقر هنا للحصول على الحجم الكامل

تشير سجلات الأحداث إلى تحطمت المحول البرمجي 0xC0000005, ، أو STATUS_ACCESS_VIOLATION. وبعد إنه أمر مضحك كيف يمكن لبناء رمز (غير قانوني) أن يجعل مترجم Segfault ...

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