Bagaimana konteks referensi ditentukan

Saya mencoba memahami aturan bagian 3.4.3.2/3 dari draf kerja akhir N3797 c++14:

Diberikan X::m (di mana X adalah namespace yang dideklarasikan pengguna), atau diberikan ::m (di mana X adalah namespace global), jika S(X, m) adalah himpunan kosong, maka program akan salah bentuk. Sebaliknya, jika S(X, m) mempunyai tepat satu anggota, atau jika konteks acuannya adalah deklarasi penggunaan (7.3.3), S(X, m) adalah himpunan deklarasi m yang diperlukan. Sebaliknya, jika penggunaan m tidak memungkinkan deklarasi unik dipilih dari S(X, m), program akan salah bentuk.

Saya telah menulis kode berikut:

inline namespace A
{
    int i = 42;
};

namespace B 
{
    static const int i = 5;
};

using B::i;

int g= ::i //S(X, i)={using B::i, A::i}

int main() { }

Seperti yang dikatakan dalam kutipan yang dikutip di atas, kita memiliki:

[...]jika S(X, m) adalah himpunan kosong[...]

S(X,m) tidak kosong, selanjutnya:

Sebaliknya, jika S(X, m) mempunyai tepat satu anggota

tidak benar, lebih lanjut:

atau jika konteks referensinya adalah deklarasi penggunaan

Saya tidak mengerti bagaimana batasan itu diperiksa pada contoh saya. Saya ingin memahami bagaimana konteks referensi ditentukan bergantung pada penggunaan referensi itu?


person Community    schedule 20.06.2014    source sumber
comment
bagian 3.4.3.2/3 dari dokumen yang mana? Saya punya tebakan, tetapi perlu waktu untuk memastikannya.   -  person Sebastian Mach    schedule 20.06.2014
comment
@phresnel Terima kasih atas komentar Anda. Saya telah mengedit pertanyaan saya.   -  person    schedule 20.06.2014


Jawaban (1)


Di sini semuanya sederhana meskipun ditulis dengan cara yang membingungkan. Entah suatu nama adalah anggota dari namespace atau namespace yang ada di dalamnya, atau nama tersebut adalah nama yang diperkenalkan oleh arahan penggunaan dari beberapa namespace lainnya. Jika nama tersebut tepat satu nama maka akan digunakan.

Dalam contoh kode Anda S( global, i ) memiliki dua anggota yang satu didefinisikan dalam namespace sebaris A dan yang lainnya diperkenalkan dengan menggunakan deklarasi. Jadi ada ambiguitas.

Jadi urutan pertimbangan namespace adalah sebagai berikut. Pada mulanya yang dipertimbangkan adalah namespace itu sendiri dan namespace yang ada di dalamnya. Jika namanya tepat satu maka digunakan.

Jika tidak, kompiler mempertimbangkan untuk menggunakan arahan. Jika sekali lagi namanya persis satu maka itu digunakan.

Dalam kasus-kasus lain, program ini tidak dirancang dengan baik.

Anda harus mempertimbangkan paragraf Standar sebelumnya

2 Untuk namespace X dan nama m, himpunan pencarian yang memenuhi syarat namespace S(X,m) didefinisikan sebagai berikut: Misalkan S0(X,m) adalah himpunan semua deklarasi m di X dan himpunan namespace sebaris dari X (7.3.1). Jika S0(X,m) tidak kosong, S(X,m) adalah S0(X,m); sebaliknya, S(X,m) adalah gabungan dari S(Ni,m) untuk semua namespace Ni dinominasikan dengan menggunakan arahan di X dan set namespace inline-nya.

EDIT: Saya minta maaf. Saya mencampurkan penggunaan deklarasi dan penggunaan direktif. Dalam contoh Anda ada deklarasi penggunaan. Jadi namanya ambigu. Id sebagai gantinya

using B::i;

akan ada

using namespace B;

maka tidak akan ada ambiguitas.

Anda harus membandingkan dua contoh

Yang pertama persis seperti yang Anda tunjukkan.

#include <iostream>

inline namespace A
{
    int i = 42;
};

namespace B 
{
    static const int i = 5;
};

using B::i;

int g= ::i;

int main() 
{
    std::cout << g << std::endl;

    return 0;
}

Kode tidak akan dikompilasi karena S( global, i ) berisi dua anggota.

Dan contoh lainnya

#include <iostream>

inline namespace A
{
    int i = 42;
};

namespace B 
{
    static const int i = 5;
};

using namespace B;

int g= ::i;

int main() 
{
    std::cout << g << std::endl;

    return 0;
}

Kode akan dikompilasi karena nama i di namespace B tidak akan dipertimbangkan.

person Vlad from Moscow    schedule 20.06.2014
comment
Terima kasih atas jawaban Anda, tetapi saya tidak setuju dengan yang berikut: Using declarations are not considered if the set is not empty.. 3.4.3.2/2 mengatakan bahwa menggunakan-directive tidak dipertimbangkan jika S(X, m) tidak kosong. - person ; 20.06.2014
comment
@Dmitry Fucintv Saya memperbarui posting saya. Saya mencampuradukkan penggunaan deklarasi dengan penggunaan direktif. Saya minta maaf. - person Vlad from Moscow; 20.06.2014
comment
Saya mengerti bagaimana S(X, m) ditentukan. Namun saya ingin menjelaskan apa sebenarnya yang dimaksud dengan aturan or if the context of the reference is a using-declaration (7.3.3), S(X, m) is the required set of declarations of m.. Dan bagaimana konteks referensi ditentukan. Bisakah Anda meningkatkan jawaban Anda? - person ; 20.06.2014
comment
@Dmitry Fucintv Tidak ada konteks referensi istilah khusus. Dalam frasa ini secara sederhana berarti bahwa nama yang direferensikan dimasukkan ke dalam namespace dengan menggunakan deklarasi. Yaitu apakah namepsace menyatakan nama itu sendiri dari nama tersebut diperkenalkan dengan menggunakan deklarasi. - person Vlad from Moscow; 20.06.2014
comment
Menurut saya batasan atau if the context of the reference is a using-declaration (7.3.3) tidak diperlukan. Itu karena deklarasi penggunaan juga merupakan deklarasi dan menurut saya itu berlebihan. Apakah saya benar? - person ; 20.06.2014