SFINAE مع غير صالحة وظيفة من نوع أو مجموعة من نوع المعلمات ؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

يرجى النظر في هذا الكود:

template<typename T>
char (&f(T[1]))[1];

template<typename T>
char (&f(...))[2];

int main() { char c[sizeof(f<void()>(0)) == 2]; }

كنت أتوقع أنها من فعل SFINAE و تنحاز الثانية الزائد ، منذ الاستبدال T في T[1] ينتج

 void [1]()

وهو نوع غير صالح ، بالطبع.تعديل أنواع المعلمة (مجموعة->مؤشر) ويتم بعد استبدال قالب المعلمات في وظيفة معلمات والتحقق من صالح الناتجة أنواع مثل 14.8.2 [temp.تقتطع] يصف.

ولكن كلا كومو و دول مجلس التعاون الخليجي تفشل في تجميع أعلاه.على حد سواء مع التشخيص المختلفة.

كومو يقول:

"ComeauTest.ج", خط 2:خطأ:مجموعة من الوظائف غير مسموح char (&f(T[1]))[1];

دول مجلس التعاون الخليجي يقول (الإصدار 4.3.3):

خطأ:ISO C++ يمنع صفر-حجم الصفيف c

يعني دول مجلس التعاون الخليجي لا تفشل في أن تكون بديلا ، لكنه يختار أول الزائد f, إرجاع sizeof 1 بدلا من الفشل إلى بديل عنه أمام مثل كومو.

ما المترجم هو الحق و هو قانون بلدي ساري المفعول في كل شيء ؟ يرجى الرجوع إلى أو الاقتباس المعيار السليم القسم في الإجابة.وذلك بفضل!


التحديث:المعيار نفسه يحتوي على مثل هذا المثال في القائمة ، 14.8.2/2.لا أدري لماذا التغاضي عن الأمر الأول:

template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); // invalid array

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

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

المحلول

ملاحظة صغيرة, على الرغم من نادرة جدا, لقد وجدت بعض المناسبات حيث أنا نعتقد أن كومو المترجم له أنه من الخطأ - على الرغم من أن هذه مناسبات نادرة بحيث دائما يستحق مزدوجة وثلاثية التحقق من الافتراضات الخاصة بك!

قد يكون سبب سلوك g++.لست متأكدا من المحدد بالضبط عندما المعلمة أنواع تعديلها:

النظر في ما يلي:

template<typename T>
struct A
{
  void bar (T[10]);
};

template<typename T>
void A<T>::bar (T*)
{
}

تعريف 'شريط' غير قانوني ، "T[10]" يضمحل إلى "T*".أنا لا لا أرى أي شيء في المعيار الذي يحظر مترجم من إجراء تعديلات 8.3.5 ضد القالب الإعلان ، كما يحسن الأداء عندما يتعلق الأمر الزائد مطابقة.

تطبيق هذا المثال الخاص بك ، g++ يمكن التعامل معه على أنه:

template<typename T>
char (&f( T* ))[1];

template<typename T>
char (&f(...))[2];

int main() { char c[sizeof(f<void()>(0)) == 2]; }

في أعلاه ، استبداله المعلمة القانونية مؤشر إلى وظيفة بدلا من مجموعة من الوظائف.

إذن السؤال بالنسبة لي هو إذا كان هناك شيء prohibts التعديلات على المعلمات وظيفة (8.3.5) مرتين ؟

شخصيا أعتقد أنه من المنطقي أن تسمح التعديلات يحدث مرتين منذ وإلا فإنه يعقد مطابقة وظيفة القالب الزائدة

في الختام أعتقد صالحة لمدة g++ لتحديد أول الزائد استنادا إلى كيفية treates المتحللة مجموعة من المعلمات ، كومو هو الخطأ لا أن يكون خصم فشل مجموعة من الوظائف.

بالطبع هذا يعني الآن (إذا كومو كانت ثابتة) ثم كل واحد مترجم أن اختيار مختلفة الزائد و ستظل المعايير متوافقة!:(

تحرير:

فقط لتوضيح وجهة نظري ، والنظر في التعليمات البرمجية التالية:

template <typename T> void foo ( T * );
template <typename T> void foo ( T * const );
template <typename T> void foo ( T [] );
template <typename T> void foo ( T [10] );
template <typename T> void foo ( T [100] );

void bar () 
{
  foo < void() > ( 0 );
}

هنا فو قد أعلن ، redeclared عدة مرات.والتي الإعلان ، لذا أي نوع المعلمة أن المترجم تطبيق القواعد الواردة في 14.8.2?

وجهة نظري هو أن المعيار لا يقول أي شيء حول ما ورد أعلاه.أنا أيضا أذهب إلى حد القول أن أي صيغة على هذا يجب أن تترك على أنها إما "غير معروف" أو "تنفيذ محددة" السلوك.

نصائح أخرى

وسوبريسينجلي بما فيه الكفاية - وهذا يعمل في VS2008. أنا لا أعتقد أن هذا بالضرورة دليلا على كونها السلوك الصحيح أم لا على الرغم من ...

والبصرية ستوديو وinterpretting

char (&f(T[1]))[1];

وبوصفها وظيفة يأخذ مجموعة من حجم 1 من T، وإرجاع إشارة إلى مجموعة من حرف من حجم 1.

سأحاول لوصف عملية قالب حجة الخصم كما فهمت من القراءة القياسية.

  1. صراحة قالب الحجج يتم التحقق كما هو موضح في 14.8.2/2.
  2. مما أدى وظيفة التوقيع تعديل في 8.3.5 (أيمجموعة مؤشر تسوس يتم تنفيذ).
  3. ضمني قالب الحجج استخلاصه كما في 14.8.2.1 (هذا يتم جزئيا استبدال التوقيع من الخطوة 2).

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

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