قالب معرف لا يطابق أي إعلان قالب

لست متأكدًا من فشل تخصيص قالب الدالة size لـ TCollection .

template 
using detect_size = decltype(std::declval().size());

template 
constexpr auto size(const C& c) -> decltype(c.size()) { return c.size(); }

template 
inline std::enable_if_t<
  !is_detected::value, size_t >
size(const C& c) { return std::distance( std::begin(c), std::end(c) ); }

template 
constexpr size_t size(const T (&array)[N]) noexcept { return N; }

template <>
auto size(const TCollection& c) { return c.GetSize(); }

يعطيني مجلس التعاون الخليجي

error: template-id 'size' for 'auto size(const TCollection&)'
does not match any template declaration

is_detected is implemented as here.

تصحيح:

  • لا يؤدي تحديد نوع الإرجاع بشكل صريح إلى تغيير أي شيء ؛
  • إذا كنت أستخدم التحميل الزائد ، فسيتم التقاط التطبيق باستخدام std :: distance .

رمز التحميل الزائد:

auto size(const TCollection& c) { return c.GetSize(); }
0
VTT أين توجد المعلمة detect_size مفقودة؟
وأضاف المؤلف SU3, مصدر
VTT هذا صحيح. يأخذ is_detected قالبًا كوسيطة أولى ، ثم يعطيه وسيطات. انظر إلى الرابط في السؤال. ليس هناك خطأ هناك.
وأضاف المؤلف SU3, مصدر
هكذا تعمل SFINAE. يمكنك تجربة التنفيذ: github.com/ivankp/ivanplib/blob/ السيد/ivanp/detect.hh
وأضاف المؤلف SU3, مصدر
أيضًا ، إذا نظرت إلى رابط cppreference ، فإن الأمثلة هناك تستخدم قوالب الاسم المستعار.
وأضاف المؤلف SU3, مصدر
قد تستخدم الزائد بدلا من ذلك.
وأضاف المؤلف Jarod42, مصدر
وأضاف المؤلف Jarod42, مصدر
يجب تحديد نوع الإرجاع بدلاً من الاعتماد على خصم نوع الإرجاع التلقائي. أيضًا معلمة القالب لـ detect_size مفقودة.
وأضاف المؤلف VTT, مصدر
يتم استخدام detect_size مرة واحدة فقط ، ويتم استخدامها مرة واحدة بدون معلمة قالب
وأضاف المؤلف VTT, مصدر
حسنًا ، لا يمكنني الوصول إلى الآن. ولكن إذا كانت is_detected تقبل القالب كوسيطة أولى ، فإن detect_size ليست معلمة صالحة. لأن detect_size هو قالب بديل.
وأضاف المؤلف VTT, مصدر

2 إجابة

الإجابة Jarod42 لا ينطبق إلا جزئيا على وضعي.

هناك أمران لم أكن أدركهما:

  1. يجب أن يعرض تخصيص نموذج الوظيفة نفس نوع الحالة الأساسية.

الطريقة الدقيقة التي يتم بها كتابة نوع الإرجاع ليست مهمة. لذلك ، بدلاً من التعريف الذي اقترحه Jarod42

template <>
std::enable_if_t::value, size_t >
size(const TCollection& c) { return c.GetSize(); }

يكفي للكتابة

template <>
size_t size(const TCollection& c) { return c.GetSize(); }
  1. لن يعمل التحميل الزائد إذا ظهر التعريف بعد استدعاء الوظيفة.

إذا تم تنظيم الكود على النحو التالي:

template 
size_t size(const T& x) { return x.size(); }

template 
std::vector reserve_same_number_of_ints(const T& x) {
  std::vector vec;
  vec.reserve(size(x));
  return vec;
}

/* specialize or overload here for special_type */

/* call reserve_same_number_of_ints on the special_type */

يتم اختيار نموذج القالب ، ولكن لا يوجد حمل زائد.

0
وأضاف

يجب عليك استخدام نفس التعريف بالضبط من قالب عام لتخصصك ، لذلك:

template <>
std::enable_if_t::value, size_t >
size(const TCollection& c) { return c.GetSize(); }

أبسط هو ببساطة استخدام الزائد:

auto size(const TCollection& c) { return c.GetSize(); }

العرض التوضيحي

0
وأضاف