سؤال

هل المثال التالي جيد الصياغة؟

namespace N {
    class A;
}
using namespace N;

class B {
    int i;
    friend class A;
};

namespace N {
    class A {
        B m;
        int get() { return m.i; }
    };
}

تم تجميع هذا المثال بنجاح باستخدام Clang 3.5، لكنه فشل مع g++ 4.8.1 مع ما يلي:

main.cpp: In member function ‘int N::A::get()’:
main.cpp:7:9: error: ‘int B::i’ is private
     int i;
         ^
main.cpp:14:30: error: within this context
         int get() { return m.i; }
                              ^

يقول معيار C++ 11 §7.3.1.2 p3،

إذا كان الاسم في friend الإعلان غير مؤهل ولا أ معرف القالب والإعلان هو وظيفة أو محدد النوع المفصل, ، فإن البحث لتحديد ما إذا كان الكيان قد تم الإعلان عنه مسبقًا يجب ألا يأخذ في الاعتبار أي نطاقات خارج مساحة الاسم الأعمق.

في المثال، class A ليس عضوا في مساحة الاسم المغلقة الأعمق (أي.مساحة الاسم العالمية)، ولكن class A يتم تقديمه باستخدام التوجيه في مساحة الاسم العالمية.

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

المحلول

أثناء استخدام مساحة الاسم N، يتم سحب الاسم N::A إلى مساحة الاسم العامة، ولا يتم الإعلان عن ذلك A في مساحة الاسم العامة.ومن ثم فإن A الإضافي في مساحة الاسم العالمية هو صديق B.رنة خاطئة.

نصائح أخرى

ليصنع N::A بدون مؤهل أ friend ل B ستستخدمه

friend A;

بدلا من

friend class A;

عند استخدام محدد نوع مفصل، على سبيل المثال، class A, ، وفي هذا النموذج المحدد، يقدم اسم فئة (انظر 3.4.4 [basic.lookup.elab] الفقرة 2).

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