Inline namespaces เป็นคุณลักษณะการกำหนดเวอร์ชันของไลบรารีคล้ายกับสัญลักษณ์การกำหนดเวอร์ชันแต่ดำเนินการอย่างหมดจดในระดับ C ++ 11 (เช่น. cross-platform) แทนที่จะเป็นคุณลักษณะของรูปแบบไบนารีที่ปฏิบัติการได้เฉพาะ (เช่นเฉพาะแพลตฟอร์ม)
มันเป็นกลไกที่ผู้เขียนห้องสมุดสามารถสร้างเนมสเปซที่ซ้อนกันและทำราวกับว่าการประกาศทั้งหมดของมันอยู่ในเนมสเปซที่ล้อมรอบ (อินสแตนซ์เนมสเปซสามารถซ้อนกันได้ดังนั้น - ใส่เนมสเปซแล้วมองและทำตัวราวกับประกาศในส่วนใดของเนมสเปซในระหว่างนั้นด้วย)
vector
เป็นตัวอย่างให้พิจารณาการดำเนินงานของ STL หากเรามีเนมสเปซแบบอินไลน์จากจุดเริ่มต้นของ C ++ ดังนั้นใน C ++ 98 ส่วนหัว<vector>
อาจมีลักษณะเช่นนี้:
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
เลือก__cplusplus
อย่างใดอย่างหนึ่งหรือการvector
ใช้งานอื่นขึ้นอยู่กับมูลค่าของ ถ้า codebase ของคุณถูกเขียนใน pre-C ++ 98 ครั้งและคุณจะพบว่า C ++ 98 รุ่นvector
เป็นสาเหตุของปัญหาสำหรับคุณเมื่อคุณอัพเกรดคอมไพเลอร์ของคุณ "ทุกคน" ที่คุณต้องทำคือการหาอ้างอิงถึงstd::vector
ใน codebase std::pre_cxx_1997::vector
และแทนที่พวกเขาโดยคุณ
มามาตรฐานต่อไปและผู้ขาย STL เพียงแค่ทำซ้ำขั้นตอนอีกครั้งแนะนำ namespace ที่ใหม่สำหรับstd::vector
กับemplace_back
การสนับสนุน (ซึ่งต้องใช้ภาษา C ++ 11) และอินไลน์ที่หนึ่ง __cplusplus == 201103L
IFF
ตกลงดังนั้นทำไมฉันต้องมีคุณสมบัติภาษาใหม่สำหรับเรื่องนี้? ฉันสามารถทำสิ่งต่อไปนี้เพื่อให้มีผลเหมือนกันได้หรือไม่?
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
ขึ้นอยู่กับมูลค่าของ__cplusplus
ฉันได้รับอย่างใดอย่างหนึ่งของการใช้งาน
และคุณเกือบจะถูกต้อง
พิจารณารหัสผู้ใช้ C ++ 98 ที่ถูกต้องต่อไปนี้ (ได้รับอนุญาตให้ใช้แม่แบบที่มีความเชี่ยวชาญอย่างเต็มรูปแบบที่อาศัยอยู่ในเนมสเปซstd
ใน 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
นี่เป็นรหัสที่ถูกต้องสมบูรณ์แบบที่ผู้ใช้ระบุการใช้เวกเตอร์ของตัวเองสำหรับประเภทของชุดที่เห็นได้ชัดว่าเธอรู้ว่ามีการใช้งานที่มีประสิทธิภาพมากกว่าที่พบใน (สำเนาของเธอ) STL
แต่ : เมื่อเชี่ยวชาญเทมเพลตคุณต้องทำในเนมสเปซที่ถูกประกาศระบบ Standard บอกว่าvector
มีการประกาศในเนมสเปซstd
ดังนั้นนั่นคือสิ่งที่ผู้ใช้คาดหวังว่าจะมีความเชี่ยวชาญเฉพาะประเภท
รหัสนี้ทำงานร่วมกับ namespace ที่ไม่ใช่ versioned std
หรือซี ++ คุณลักษณะ namespace 11 แบบอินไลน์ แต่ไม่ได้มีเคล็ดลับเวอร์ชันที่ใช้using namespace <nested>
เพราะ exposes ว่ารายละเอียดการดำเนินงานว่า namespace จริงที่vector
ถูกกำหนดไม่ได้std
โดยตรง
มีช่องอื่น ๆ ที่คุณสามารถตรวจสอบเนมสเปซที่ซ้อนกัน (ดูความคิดเห็นด้านล่าง) แต่อินไลน์เนมสเปซจะเสียบมันทั้งหมด และนั่นคือทั้งหมดที่มีให้มัน มีประโยชน์อย่างมากสำหรับอนาคต แต่ AFAIK Standard ไม่ได้กำหนดชื่อแบบอินไลน์เนมสเปซสำหรับไลบรารี่มาตรฐานของตัวเอง มาตรฐานตัวเอง (เว้นแต่ผู้ขายคอมไพเลอร์เห็นด้วยกับรูปแบบการตั้งชื่อ)
using namespace V99;
ไม่ทำงานในตัวอย่างของ Stroustrup