سؤال

أثناء محاولة الإجابة هذا السؤال أردت أن أقترح استخدام enable_if + disable_if للسماح بالحمل الزائد للطريقة بناءً على حقيقة أن النوع كان (أو لا) متعدد الأشكال.

لذلك قمت بإنشاء ملف اختبار صغير:

template <class T>
void* address_of(T* p,
                 boost::enable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return dynamic_cast<void*>(p); }

template <class T>
void* address_of(T* p,
                 boost::disable_if< boost::is_polymorphic<T> >* dummy = 0)
{ return static_cast<void*>(p); }

struct N { int x; };


int main(int argc, char* argv[])
{
  N n;
  std::cout << address_of(&n) << std::endl;
  return 0;
}

الذي يبدو ترويضا تماما.

ومع ذلك GCC (3.4 ...) خنق على هذا:

test.cpp: في الوظيفة int main(int, char**):
test.cpp: 29: خطأ: Call of Overloading address_of(N*) غامض
Test.CPP: 17: ملاحظة: المرشحون هم: void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*) مع t = n
test.cpp: 20: ملاحظة: void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*) مع t = n

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

لقد قمت بتصحيحه باستخدام ... (القطع النخاعية) بدلا من disable_if ويتطلب حجة ثانية وهمية ... لكنني ما زلت مهتمًا بالسبب في اختنق المترجم في هذا الأمر.

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

المحلول

اختنق المترجم لأنك نسيت الفائدة ::type على enable_if و disable_if. يتم تعريف القوالب دائمًا ؛ إنه مجرد العضو type موجود إذا وفقط إذا كان التعبير true (إلى عن على enable_if) أو false (إلى عن على disable_if).

template <class T>
void* address_of(T* p,
                 أكتب اسم boost::enable_if< boost::is_polymorphic<T> >::يكتب* dummy = 0)
{ return dynamic_cast<void*>(p); }

template <class T>
void* address_of(T* p,
                 أكتب اسم boost::disable_if< boost::is_polymorphic<T> >::يكتب* dummy = 0)
{ return static_cast<void*>(p); }

بدون زائدة ::type, ، قوالب وظيفتك فقط تنشئ أحمالًا زائدة تأخذ مؤشرات إلى مثيلات من enable_if أو disable_if كمعلمة ثانية. مع الزائدة ::type, ، إما أن تقوم القوالب بإنشاء تحميل زائد مع معلمة ثانية من النوع void*, أو تتم إزالة الحمل الزائد (أي السلوك المطلوب).

نصائح أخرى

باستخدام إصدار "نوع الإرجاع" من enable_if يعمل في 3.4.4: gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <iostream>

template <class T>
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return dynamic_cast<void*>(p); }

template <class T>
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p)
{ return static_cast<void*>(p); }

struct N { int x; };


int main(int argc, char* argv[])
{
  N n;
  std::cout << address_of(&n) << std::endl;
  return 0;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top