c++ - نهائي - معنى قبول جامعي غير مشروط




نوع الإرجاع المشروط للمشغل والبحث على مرحلتين (2)

أعتقد أن مجلس التعاون الخليجي (والاستوديو البصري ، بالمناسبة) على حق في هذا.

n4582 ، § 14.6.2.2

باستثناء ما هو موضح أدناه ، فإن التعبير يعتمد على الكتابة إذا كان أي تعبير فرعي يعتمد على الكتابة.

في T{} ? d : d T{} ? d : d ، هناك 3 تعبيرات فرعية:

  • T{} ، من الواضح أن اكتب تابع
  • d (2 مرات) ، لا تعتمد على النوع

نظرًا لوجود تعبير فرعي تابع للنوع ولا يُشغل المشغل الثلاثي في ​​قائمة الاستثناءات الواردة في الفقرة 2.1.6.6.6 ، فإنه يعتبر من النوع المعتمد.

النظر في المقتطف التالي:

struct Base { };
struct Derived : Base { };

void f(Base &) { std::cout << "f(Base&)\n"; }

template <class T = int>
void g() {
    Derived d;
    f(T{} ? d : d); // 1
}

void f(Derived &) { std::cout << "f(Derived&)\n"; }

int main() {
    g();
}

في هذه الحالة ، أعتقد أنه يجب البحث عن استدعاء الدالة إلى f في // 1 في المرحلة الأولى ، نظرًا لأن نوع الوسيط الخاص بها Derived& بشكل لا لبس فيه ، وبالتالي يتم حلها على f(Base&) وهو الوحيد في النطاق.

يتفق Clang 3.8.0 معي ، لكن GCC 6.1.0 لا ، ويؤجل البحث عن f حتى المرحلة الثانية ، حيث يتم التقاط f(Derived&) .

المترجم الذي هو الصحيح؟


باستخدام أحدث إصدار من معيار C ++ حاليًا n4582 .

في القسم 14.6 (صفحة 10) ، يشير التقرير إلى أن الاسم ملزم عند نقطة الإعلان إذا كان الاسم لا يعتمد على معلمة قالب. إذا كان يعتمد على معلمة قالب ، فسيتم تعريف ذلك في القسم 14.6.2.

يمضي القسم 14.6.2.2 ليقول أن التعبير يعتمد على الكتابة إذا كان أي تعبير فرعي يعتمد على الكتابة.

الآن لأن الدعوة إلى f() تعتمد على المعلمة الخاصة بها. أنت تنظر إلى نوع المعلمة لمعرفة ما إذا كان يعتمد على النوع. المعلمة هي False<T>::value ? d : d False<T>::value ? d : d . هنا الشرط الأول يعتمد على نوع T

لذلك نخلص إلى أن الدعوة ملزمة عند نقطة إنشاء مثيل لا إعلان. وبالتالي يجب الربط بـ: void f(Derived &) { std::cout << "f(Derived&)\n"; } void f(Derived &) { std::cout << "f(Derived&)\n"; }

وبالتالي g ++ لديه تنفيذ أكثر دقة.

14.6 تحليل الاسم [temp.res]

الفقرة 10:

إذا كان الاسم لا يعتمد على معلمة قالب (كما هو محدد في 14.6.2) ، فسيكون الإعلان (أو مجموعة من الإعلانات) لهذا الاسم في نطاقه عندما يظهر الاسم في تعريف القالب ؛ الاسم مرتبط بالإعلان (أو الإعلانات) الموجودة في تلك المرحلة ولا يتأثر هذا الربط بالإعلانات المرئية عند نقطة النسخ.

14.6.2.2 التعبيرات المعتمدة على الكتابة [temp.dep.expr]

باستثناء ما هو موضح أدناه ، فإن التعبير يعتمد على الكتابة إذا كان أي تعبير فرعي يعتمد على الكتابة .





dependent-name