سؤال

ماذا يقول السؤال. بالإضافة إلى ذلك ، هل من الممكن القيام بذلك مضمّنًا؟

إليك مثال صغير فقط لإعطاء فكرة ...

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void do( const Foo<T> &f ) {
    z = f.z;
  }
  // specialize 'do' for Foo<int>, possible inline?

 private:
  T z;
};
هل كانت مفيدة؟

المحلول

يمكنك الحصول على هذا السلوك من خلال جعل وظيفة العضو قالب وظيفة العضو واستخدام SFINAE (فشل الاستبدال ليس خطأ). فمثلا:

template <typename U>
typename std::enable_if<!std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

template <typename U>
typename std::enable_if<std::is_integral<U>::value && 
                        std::is_same<T, U>::value, void>::type
f(const Foo<U>& x)
{
}

ال is_integral اكتب اختبار السمات سواء U هو نوع عدد صحيح. إذا لم يكن كذلك ، يتم إنشاء الأول ؛ إذا كان ذلك ، يتم إنشاء مثيل للثاني.

ال is_same اكتب اختبارات السمات للتأكد T و U هي نفس النوع. يتم استخدام هذا لضمان عدم إنشاء قالب وظيفة العضو لأي نوع غيره Foo<T>.

هذا المثال يستخدم C ++ 0x <type_traits> مكتبة؛ تعزيز أيضا مكتبة سمات النوع التي يمكنك استخدامها ، والتي تعمل في الغالب.

نصائح أخرى

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

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    doItImpl(f);
  }

 private:
  template<typename U>
  void doItImpl(const Foo<U> &f) {
    z = f.z;
  }

  void doItImpl(const Foo<int> &f) {
    /* ... */
  }

 private:
  T z;
};

أو ، في هذه الحالة ، يمكنك القيام بذلك عن طريق التخصص

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  void doIt(const Foo<T> &f ) {
    z = f.z;
  }

 private:
  T z;
};

template<>
inline void Foo<int>::doIt(const Foo<int> &f) {
  /* ... */
}

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

قد تحاول أن تفعل شيئًا كهذا (لم يختبر ، قد لا يعمل):

template<typename T>
class Foo {
 public:
  Foo() :z(0.0) {}

  template<typename Ty = T>
  void do( const Foo<T> &f ) {
    z = f.z;
  }

  template<>
  void do<int>( const Foo<T> &f ) {
    //specialized code
  }

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