نشر "typedef" من الفئة المستندة إلى الفئة المشتقة لـ "القالب"

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

سؤال

أحاول تحديد الفئة الأساسية التي تحتوي على typedef فقط.

template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
private:
    Vec_t v;  // fails - Vec_t is not recognized
};

لماذا أتلقى في B خطأ مفاده أنه لم يتم التعرف على Vec_t وأحتاج إلى كتابته بشكل صريح؟

typename A<T>::Vec_t v;
هل كانت مفيدة؟

المحلول

أعتقد أن هذا السؤال مكرر، لكن لا يمكنني العثور عليه الآن.يقول معيار C++ أنه يجب عليك تأهيل الاسم بالكامل وفقًا لـ 14.6.2/3:

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

محدث: لقد وجدت نسخة مكررة أخيرًا: ها هو.

نصائح أخرى

وهناك ما يسمى تعتمد و<م> nondependent الأسماء في حالة القوالب.

إذا يعتمد الاسم على معلمة قالب T لها <م> يعتمد اسم وغيرهم الذين لا تعتمد على المعلمة T و<م> مستقلة أسماء.

<اقتباس فقرة>   

وهنا القاعدة: المترجم لا   ابحث في الفئات الأساسية التي تعتمد (مثل   A) عند البحث عن nondependent   أسماء (مثل Vec_t). كنتيجة ل،   المترجم لا يعرفون أنهم حتى   موجودة ناهيك هي أنواع.

ومترجم لا يمكن أن نفترض أن Vec_t هو نوع حتى يعرف T لأن هناك تخصص محتملا للA<T> حيث A<T>:: Vec_t هو عضو البيانات

وبالتالي فإن الحل هو استخدام typename

 typename A<T>::Vec_t v;  ← good

وأوصي تذهب من خلال هذا https://isocpp.org/ ويكي / أسئلة وأجوبة / القوالب #-أنواع-اسم nondependent-بحث .

قديم (كسر) رابط: HTTP: // شبكة الاتصالات العالمية. parashift.com/c++-faq-lite/templates.html#faq-35.18

ولأن المترجم ليس على يقين من أن أسماء Vec_t نوع. على سبيل المثال، قد يكون A<T> متخصصة لT=int إلى <م> لا التي لها نفس typedef وجه الخصوص.

للاكتمال، إليك كيفية تخفيف هذا الإزعاج قليلاً، إما:

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

template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
public:
    using typename A<T>::Vec_t;
    // .........

private:
    Vec_t v;
};

يمكن أن يكون مفيدًا إذا كان لديك أكثر من ذكر للموروثة typedef في الطبقة المشتقة.كما لا تحتاج إلى إضافة typename في كل مرة مع هذا.

وتحتاج إلى تأهيل صراحة استخدام Vec_t لأن المترجم لا يعرف من أين يأتي Vec_t من.

لا يمكن تحمل أي شيء عن هيكل A، لأن الطبقة قالب A قد تكون متخصصة. ويمكن أن تشمل التخصص في Vec_t وهي ليست typedef و، أو أنه قد لا تشمل حتى Vec_t عضوا على الإطلاق.

وVec_t ليس اسما معتمدا، والمترجم يحتاج إلى معرفة ما هو عليه دون instantiating أية قوالب (الفئة الأساسية في هذه الحالة). انها حقا لا يختلف عن:

template <class T>
class X
{
    std::string s;
}

وهنا أيضا يحتاج المترجم إلى معرفة الأمراض المنقولة جنسيا :: سلسلة حتى إذا لم يتم إنشاء مثيل X، لأن الاسم لا تعتمد على حجة قالب T (بقدر المترجم يمكن أن تتحمل).

والكل في الكل، typedefs في فئة أساسية قالب تبدو عديمة الفائدة وليس لاستخدامها في فئة مشتقة. وtypedefs مفيدة للمستخدم، ولكن.

وهذا المفهوم يمكن أن تترافق مع كيفية استخدامنا std::vector<T>. على سبيل المثال، إذا كان لدينا std::vector<int> Foo. الآن، قررنا استخدام أي من انها أنواع الأعضاء، دعنا نقول لiterator. في هذا السيناريو نذكر صراحة

std::vector<int>::iterator foo_iterator;

وبالمثل في قضيتك، من أجل استخدام Vec_t نوع عضو عام من template <typename T> class A، تحتاج إلى نعلن ذلك صراحة

A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top