سؤال

كنت أنا وصديق نناقش قوالب C++.سألني ماذا يجب أن يفعل هذا:

#include <iostream>

template <bool>
struct A {
    A(bool) { std::cout << "bool\n"; }
    A(void*) { std::cout << "void*\n"; }
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new A< b > (c) > (d);
}

يحتوي السطر الأخير في main على تحليلين معقولين.هل "ب" هي وسيطة القالب أم أنها b > (c) حجة القالب؟

ورغم أنه من التافه أن نجمع هذا، ونرى ما سنحصل عليه، إلا أننا كنا نتساءل ما الذي يحل الغموض؟

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

المحلول

AFAIK سيتم تجميعها كـ new A<b>(c) > d.هذه هي الطريقة الوحيدة المعقولة لتحليلها IMHO.إذا لم يتمكن المحلل اللغوي في ظل الظروف العادية من افتراض إنهاء وسيطة القالب، فقد يؤدي ذلك إلى مزيد من الغموض.وإذا أردت الأمر بطريقة أخرى، كان عليك أن تكتب:

new A<(b > c)>(d);

نصائح أخرى

وكما ذكر Leon & Lee، فإن 14.2/3 (C++ '03) يحدد هذا السلوك بشكل واضح.

يضيف C++ '0x إلى المتعة مع تطبيق قاعدة مماثلة على >>.المفهوم الأساسي هو أنه عند تحليل قائمة وسائط القالب، تكون القائمة غير متداخلة >> سيتم التعامل مع اثنين متميزة > > الرموز المميزة وليس مشغل التحول الصحيح:

template <bool>
struct A {
  A(bool);
  A(void*);
};

template <typename T>
class C
{
public:
  C (int);
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new C <A< b  >>  (c) > (d); // #1
    new C <A< b > >  (c) > (d); // #2
}

"#1" و"#2" متكافئان فيما سبق.

يؤدي هذا بالطبع إلى إصلاح هذا الإزعاج الناتج عن الاضطرار إلى إضافة مسافات في التخصصات المتداخلة:

C<A<false>> c;  // Parse error in C++ '98, '03 due to "right shift operator"

يحدد معيار C++ أنه إذا كان اسم القالب متبوعًا بـ a <, ، ال < هي دائمًا بداية قائمة وسيطات القالب والأولى غير المتداخلة > يتم اعتباره نهاية قائمة وسائط القالب.

إذا كنت تقصد أن نتيجة > عامل التشغيل هو وسيطة القالب، فستحتاج إلى وضع التعبير بين قوسين.لا تحتاج إلى أقواس إذا كانت الوسيطة جزءًا من a static_cast<> أو تعبير قالب آخر.

من المحتمل أن يكون جشع المعجم هو العامل الحاسم في غياب الأقواس لتوضيح الأمر.أعتقد أن المعجم ليس جشعًا.

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