دول مجلس التعاون الخليجي المسألة:باستخدام عضوا في الفئة الأساسية التي يعتمد على قالب الحجة

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

سؤال

التعليمة البرمجية التالية لا تجمع مع دول مجلس التعاون الخليجي ، ولكن مع Visual Studio:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << foo << endl; }
};

أحصل على خطأ:

test.cpp:في وظيفة عضو 'الفراغ ب::شريط()':

الاختبار.cpp:11:خطأ:'فو' لم تعلن في هذا النطاق

ولكن ينبغي أن يكون!إذا قمت بتغيير bar إلى

void bar() { cout << this->foo << endl; }

ثم لا ترجمة, ولكن أنا لا أعتقد أنني يجب أن تفعل هذا.هل هناك شيء في المواصفات الرسمية من C++ في أن دول مجلس التعاون الخليجي هي التالية هنا أم أنها مجرد نزوة?

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

المحلول

هذا تغير في دول مجلس التعاون الخليجي-3.4.C++ محلل حصلت على أكثر من ذلك بكثير صارمة في هذا الإصدار -- في المواصفات ولكن لا يزال نوعا ما مزعج للناس مع إرث أو منصة متعددة قواعد رمز.

نصائح أخرى

ديفيد جوينر كان التاريخ هنا هو السبب.

المشكلة عند ترجمة B<T> هو أن الفئة الأساسية A<T> غير معروف من المترجم ، كونها فئة القالب, لذلك لا سبيل مترجم إلى معرفة أي من أعضاء الفئة الأساسية.

الإصدارات السابقة بعض الاستدلال من خلال تحليل قاعدة قالب الفئة ، ولكن ISO C++ ذكر أن هذا الاستدلال يمكن أن تؤدي إلى الصراعات حيث لا ينبغي أن يكون هناك.

الحل الرجوع إلى قاعدة الطبقة الأعضاء في قالب هو استخدام this (كما فعلت) أو على وجه التحديد اسم الفئة الأساسية:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << A<T>::foo << endl; }
};

مزيد من المعلومات في دول مجلس التعاون الخليجي دليل.

نجاح باهر.C++ لم يتوقف مفاجأة لي مع غرابة.

في قالب التعريف غير مؤهلين أسماء لم يعد يجد أعضاء تعتمد على قاعدة (كما هو محدد من قبل [temp.dep]/3 في C++ القياسية).على سبيل المثال ،

template <typename T> struct B {
  int m;
  int n;
  int f ();
  int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
  void h ()
  {
    m = 0; // error
    f ();  // error
    n = 0; // ::n is modified
    g ();  // ::g is called
  }
};

يجب أن تجعل أسماء تعتمد ، على سبيل المثالقبل التقديم لهم مع هذا->.هنا هو تصحيح تعريف ج::ح ،

template <typename T> void C<T>::h ()
{
  this->m = 0;
  this->f ();
  this->n = 0
  this->g ();
}

كما حل بديل (للأسف ليس إلى الوراء متوافقة مع دول مجلس التعاون الخليجي 3.3), يمكنك استخدام باستخدام الإعلانات بدلا من هذا-->:

template <typename T> struct C : B<T> {
  using B<T>::m;
  using B<T>::f;
  using B<T>::n;
  using B<T>::g;
  void h ()
  {
    m = 0;
    f ();
    n = 0;
    g ();
  }
};

وهذا فقط كل أنواع الجنون.شكرا يا ديفيد.

هنا هو "درجة الحرارة.dep/3" القسم القياسية [ISO/IEC 14882:2003] أنها تشير إلى:

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

typedef double A; 
template<class T> class B { 
    typedef int A; 
}; 
template<class T> struct X : B<T> { 
    A a; // a has typedouble 
}; 

اسم النوع A في تعريف X<T> يربط الرموز المميزة ل typedef اسم معرف في مساحة العالمي النطاق ، ليس typedef اسم معرف في قاعدة الطبقة B<T>.] [على سبيل المثال:

struct A { 
    struct B { /* ... */ }; 
    int a; 
    int Y; 
}; 
int a; 
template<class T> struct Y : T { 
    struct B { /* ... */ }; 
    B b; //The B defined in Y 
    void f(int i) { a = i; } // ::a 
    Y* p; // Y<T> 
}; 
Y<A> ya; 

أعضاء A::B, A::a, ، A::Y القالب الحجة A لا تؤثر على ربط الأسماء في Y<A>. ]

السبب الرئيسي C++ لا يمكن أن تتحمل أي شيء هنا هو أن قاعدة قالب يمكن أن تكون متخصصة لنوع لاحقا.استمرار الأصلي على سبيل المثال:

template<>
class A<int> {};

B<int> x; 
x.bar();//this will fail because there is no member foo in A<int>

VC لا تنفذ على مرحلتين البحث ، في حين أن دول مجلس التعاون الخليجي لا.حتى دول مجلس التعاون الخليجي يوزع قوالب قبل أن يتم إنشاء مثيل وبالتالي يجد أخطاء أكثر من VC.في المثال الخاص بك ، فو تعتمد على الاسم لأنه يعتمد على 'T'.إلا إذا كنت تقول المترجم حيث أنه يأتي من أنه لا يمكن التحقق من صحة النموذج في كل شيء ، قبل مثيل.لهذا السبب عليك أن تخبر المترجم حيث أنها تأتي من.

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