سؤال

هل التصميم التالي ممكن؟:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

الآن إذا كان ذلك ممكنًا ، فسأقوم ببعض التخصصات الصريحة لـ Dosomething حتى يكون لدي بعض الإصدارات في النهاية مثل:

void doSomething<int>(){
 //do something
}
void doSomething<double>(){
 //do something
}
...etc

يبدو الأمر مستحيلًا ، لا يمكنني العثور على أي بناء جملة للقيام بالمهمة ، ثم اعتقدت أنه ربما يكون التصميم كما يلي بحيث يجب تمرير جميع وسائط القالب إلى فئة القالب نفسها:

template <typename T,typename Z>
class Test{
 public:
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

ثم حاولت التخصص الجزئي الذي لم يتجمع:

template <typename T>
void Test<T,int>::doSomething(){
 //do something
}
template <typename T>
void Test<T,double>::doSomething(){
 //do something
}
...etc

حصلت على الأخطاء التالية للتخصص الصريح:
خطأ#1: قائمة الوسيطة القالب التالية يجب أن يسرد اسم قالب الفئة المعلمات بالترتيب المستخدم في قائمة المعلمات القالب.
الخطأ رقم 2: 'Container1': عدد قليل جدًا من وسائط القالب.

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

المحلول

من أجل التخصص بشكل صريح doSomething عليك أيضًا أن تتخصص بشكل صريح Test.

من 14.7.3/18:

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

نصائح أخرى

لا يمكنك التخصص بشكل صريح في قالب عضو ما لم يتم التخصص بشكل صريح أيضًا.

لذلك فقط شيء من هذا القبيل سوف يعمل:

template<> template<>
void Test<int>::doSomething<int>()
{
}

يمكنك دائمًا جعل الوظيفة مضمنة

template <class T>
class Test
{
public:
 template <class Z>
 void doSomething() { cout << "default" << endl; }

 template<>
 void doSomething<int>() { cout << "int" << endl;}
 template<>
 void doSomething<double>() { cout << "double" << endl; }
private:
 T obj;
};

أعتقد أن هذا واحد صعب الإرضاء. أفترض أنه لا يمكنك فعل ذلك ، اقرأ هذه.

لست متأكدًا مما إذا كان هذا خطأ في G ++ ولكن هذا يجمع وينتج ما أتوقعه.

#include<typeinfo>
#include<iostream>

template<typename T>
class Test
{
public:
    template<typename Z>
    void doSomething();

private:
    T obj;
};

template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
    Z val;
    std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}

int main(int argc, char *argv[])
{
    Test<double> a;
    a.doSomething<int>();
    a.doSomething<double>();
}

نشرت Icecrime إجابة مؤقتة ويتم تجميعها بسبب بعض الأخطاء التي ربما بواسطة Visual C ++ 2008:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
 //do something
}

تحقق من إجابته الحالية رغم ذلك. إن الشيء المضحك على الأقل مع VC ++ 2008 هو ، لا توجد مشكلة في التجميع عند التخصص مع التعريفات المضمنة ، ولكن للتخصصات ذات التعريفات غير الخطية بمجرد أن يكون هناك أكثر من إصدار واحد ، لا يتم تجميعه بنجاح.

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