Mengapa ada nama kelas yang disuntikkan?

147

Baru-baru ini, saya melihat fitur C ++ yang aneh: nama kelas yang disuntikkan .

class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...

Tapi saya tidak tahu mengapa fitur ini diperlukan. Apakah ada latihan yang memerlukan fitur ini?

Dan saya mendengar fitur ini tidak ada di C ++ lama. Lalu, kapan diperkenalkan? C ++ 03? C ++ 11?

ikh
sumber
Sobat, bisakah kamu melihat di Skype? Saya tidak bisa menghubungi Anda
Irinel Iovan

Jawaban:

162

Nama kelas yang disuntikkan berarti yang Xdideklarasikan sebagai anggota X, sehingga pencarian nama di dalam Xselalu menemukan kelas saat ini, bukan yang lain Xyang mungkin dideklarasikan pada cakupan yang sama, misalnya

void X() { }
class X {
public:
  static X create() { return X(); }
};

Apakah create()fungsi membuat Xobjek sementara atau memanggil fungsi X? Pada lingkup namespace ia akan memanggil fungsi, jadi tujuan dari nama kelas yang disuntikkan adalah untuk memastikan bahwa di dalam tubuh Xnama selalu menemukan kelas itu sendiri (karena pencarian nama dimulai dalam ruang lingkup kelas sendiri sebelum melihat di dalam melampirkan cakupan).

Ini juga membantu di dalam templat kelas, di mana nama kelas yang disuntikkan dapat digunakan tanpa daftar argumen templat, misalnya menggunakan hanya Fooalih-alih templat-id lengkap Foo<blah, blah, blah>, sehingga mudah untuk merujuk ke instantiasi saat ini. Lihat DR 176 untuk perubahan antara C ++ 98 dan C ++ 03 yang mengklarifikasi itu.

Gagasan nama kelas yang disuntikkan hadir dalam C ++ 98, tetapi terminologinya baru untuk C ++ 03.

C ++ 98 mengatakan:

Sebuah kelas nama dimasukkan ke dalam lingkup di mana dinyatakan segera setelah kelas-nama terlihat. Nama kelas juga dimasukkan ke dalam ruang lingkup kelas itu sendiri.

Kalimat kedua diubah oleh DR 147 sehingga C ++ 03 mengatakan dalam [class] / 2:

Sebuah kelas nama dimasukkan ke dalam lingkup di mana dinyatakan segera setelah kelas-nama terlihat. Nama kelas juga dimasukkan ke dalam ruang lingkup kelas itu sendiri; ini dikenal dengan nama kelas yang disuntikkan .

Bahkan sebelum C ++ 98, ARM memiliki kata-kata yang kira-kira setara yang berarti nama kelas selalu dapat digunakan di badan kelas untuk merujuk ke kelas itu sendiri:

Nama kelas dapat digunakan sebagai nama kelas bahkan di dalam daftar anggota penentu kelas itu sendiri.

  • Sebagai contoh,

    class link { link* next; };

Jonathan Wakely
sumber
2
Saya sering ditanya, tetapi tidak pernah bisa membangun contoh sederhana yang menunjukkan masalah. Jadi +1 sebagai contoh.
dhein
1
Ini dapat dilihat dengan jelas jika Anda menjalankan clang ++ your_program.cpp -Xclang -ast-dump dan Anda melihat kelas Anda dan kemudian simpul anak kelas yang disuntikkan.
xaxxon