Ruang nama sebaris adalah fitur versi perpustakaan yang mirip dengan versi simbol , tetapi diterapkan murni pada level C ++ 11 (mis. Lintas-platform) alih-alih menjadi fitur format biner yang dapat dieksekusi spesifik (mis. Platform-spesifik).
Ini adalah mekanisme di mana penulis perpustakaan dapat membuat tampilan namespace bersarang dan bertindak seolah-olah semua deklarasi berada di namespace sekitarnya (inline namespaces dapat bersarang, sehingga "lebih-bersarang" nama-nama merembes sampai ke non pertama -inama namespace dan lihat dan bertindak seolah-olah deklarasi mereka ada di salah satu ruang nama di antara keduanya).
Sebagai contoh, pertimbangkan penerapan STL untuk vector
. Jika kita memiliki ruang nama inline dari awal C ++, maka dalam C ++ 98 header <vector>
mungkin terlihat seperti ini:
namespace std {
#if __cplusplus < 1997L // pre-standard C++
inline
#endif
namespace pre_cxx_1997 {
template <class T> __vector_impl; // implementation class
template <class T> // e.g. w/o allocator argument
class vector : __vector_impl<T> { // private inheritance
// ...
};
}
#if __cplusplus >= 1997L // C++98/03 or later
// (ifdef'ed out b/c it probably uses new language
// features that a pre-C++98 compiler would choke on)
# if __cplusplus == 1997L // C++98/03
inline
# endif
namespace cxx_1997 {
// std::vector now has an allocator argument
template <class T, class Alloc=std::allocator<T> >
class vector : pre_cxx_1997::__vector_impl<T> { // the old impl is still good
// ...
};
// and vector<bool> is special:
template <class Alloc=std::allocator<bool> >
class vector<bool> {
// ...
};
};
#endif // C++98/03 or later
} // namespace std
Tergantung pada nilai __cplusplus
, salah satu atau vector
implementasi lainnya dipilih. Jika basis kode Anda ditulis dalam pra-C ++ 98 kali, dan Anda menemukan bahwa versi C ++ 98 vector
menyebabkan masalah bagi Anda ketika Anda memutakhirkan kompiler Anda, "yang harus Anda lakukan adalah menemukan referensi std::vector
di basis kode Anda dan ganti dengan std::pre_cxx_1997::vector
.
Datang standar berikutnya, dan vendor STL hanya mengulangi prosedur itu lagi, memperkenalkan namespace baru std::vector
dengan emplace_back
dukungan (yang membutuhkan C ++ 11) dan sebaris satu iff __cplusplus == 201103L
.
OK, jadi mengapa saya perlu fitur bahasa baru untuk ini? Saya sudah bisa melakukan yang berikut untuk memiliki efek yang sama, bukan?
namespace std {
namespace pre_cxx_1997 {
// ...
}
#if __cplusplus < 1997L // pre-standard C++
using namespace pre_cxx_1997;
#endif
#if __cplusplus >= 1997L // C++98/03 or later
// (ifdef'ed out b/c it probably uses new language
// features that a pre-C++98 compiler would choke on)
namespace cxx_1997 {
// ...
};
# if __cplusplus == 1997L // C++98/03
using namespace cxx_1997;
# endif
#endif // C++98/03 or later
} // namespace std
Bergantung pada nilai __cplusplus
, saya mendapatkan salah satu atau yang lain dari implementasi.
Dan Anda akan hampir benar.
Pertimbangkan kode pengguna C ++ 98 yang valid berikut ini (sudah diizinkan untuk sepenuhnya mengkhususkan templat yang tinggal di namespace std
dalam C ++ 98):
// I don't trust my STL vendor to do this optimisation, so force these
// specializations myself:
namespace std {
template <>
class vector<MyType> : my_special_vector<MyType> {
// ...
};
template <>
class vector<MyOtherType> : my_special_vector<MyOtherType> {
// ...
};
// ...etc...
} // namespace std
Ini adalah kode yang benar-benar valid di mana pengguna memasok implementasi sendiri dari vektor untuk satu set jenis di mana ia tampaknya tahu implementasi yang lebih efisien daripada yang ditemukan dalam (salinannya) STL.
Tetapi : Ketika mengkhususkan suatu templat, Anda perlu melakukannya di namespace yang dideklarasikan. Standar mengatakan itu vector
dideklarasikan dalam namespace std
, jadi di situlah pengguna berhak mengharapkan untuk mengkhususkan jenis.
Kode ini berfungsi dengan namespace non-versi std
, atau dengan fitur namespace C ++ 11 inline, tetapi tidak dengan trik versi yang digunakan using namespace <nested>
, karena itu memperlihatkan detail implementasi yang namespace sebenarnya yang vector
didefinisikan tidak std
secara langsung.
Ada lubang lain di mana Anda dapat mendeteksi namespace bersarang (lihat komentar di bawah), tetapi inpasi namespace pasang semuanya. Dan hanya itu yang ada untuk itu. Sangat berguna untuk masa depan, tetapi AFAIK Standar tidak meresepkan nama namespace inline untuk pustaka standarnya sendiri (meskipun, saya senang terbukti salah tentang hal ini), jadi itu hanya dapat digunakan untuk perpustakaan pihak ketiga, tidak standar itu sendiri (kecuali vendor kompiler menyetujui skema penamaan).
using namespace V99;
tidak berfungsi dalam contoh Stroustrup.