Yani ana noktaları özetlemek için using namespace v99ve inline namespaceaynı değildi, eski kullanarak sorunlarını sabit C ++ 11'de tanıtıldı özel bir anahtar kelime (inline) önce versiyon kütüphaneleri için bir geçici çözüm oldu usingaynı sürüm işlevselliği sunarken,. Kullanma using namespaceADL ile neden problemlerine kullanılan (ADL şimdi izleyin görünse de usingdirektifler) ve dışı hattı vb kütüphane sınıf / fonksiyon uzmanlık kullanıcı tarafından değil iş olan gerçek ad alanının bitti dışında (isim olsaydı kullanıcı bilmeyecek ve bilmeyecektir, yani kullanıcı, uzmanlığın çözülmesi için B :: yerine B :: abi_v2 :: kullanmalıdır).
//library code
namespace B { //library name the user knows
namespace A { //ABI version the user doesn't know about
template<class T> class myclass{int a;};
}
using namespace A; //pre inline-namespace versioning trick
}
// user code
namespace B { //user thinks the library uses this namespace
template<> class myclass<int> {};
}
Bu statik bir analiz uyarısı gösterecektir first declaration of class template specialization of 'myclass' outside namespace 'A' is a C++11 extension [-Wc++11-extensions]. Ancak, ad alanı A satır içi yaparsanız, derleyici uzmanlığı doğru bir şekilde çözer. Bununla birlikte, C ++ 11 uzantılarında sorun ortadan kalkar.
Hat dışı tanımlar kullanılırken çözülmez using; iç içe / iç içe olmayan bir uzantı ad alanı bloğunda bildirilmeleri gerekir (bu, herhangi bir nedenle, bir işlevi kendi uygulamalarını sağlamalarına izin verildiyse, kullanıcının ABI sürümünü tekrar bilmesi gerektiği anlamına gelir).
#include <iostream>
namespace A {
namespace B{
int a;
int func(int a);
template<class T> class myclass{int a;};
class C;
extern int d;
}
using namespace B;
}
int A::d = 3; //No member named 'd' in namespace A
class A::C {int a;}; //no class named 'C' in namespace 'A'
template<> class A::myclass<int> {}; // works; specialisation is not an out-of-line definition of a declaration
int A::func(int a){return a;}; //out-of-line definition of 'func' does not match any declaration in namespace 'A'
namespace A { int func(int a){return a;};} //works
int main() {
A::a =1; // works; not an out-of-line definition
}
B sıralı yapılırken sorun ortadan kalkar.
Diğer işlev inlinead alanları, kütüphane yazarının 1) kullanıcıyı yeni ad alanı adıyla kodu yeniden düzenlemeye zorlamadan ve 2) ayrıntı eksikliğini önleme ve 3) API ile ilgili olmayan ayrıntıların soyutlanmasını sağlamadan kütüphaneye şeffaf bir güncelleme sağlamasına izin verir, 4) ise, satır içi olmayan bir ad alanı kullanmanın sağlayabileceği aynı yararlı bağlayıcı tanı ve davranışını vermek. Bir kütüphane kullandığınızı varsayalım:
namespace library {
inline namespace abi_v1 {
class foo {
}
}
}
Kullanıcının library::foo, daha temiz görünen belgelerdeki ABI sürümünü bilmesine veya eklemesine gerek kalmadan arama yapmasına olanak tanır . Kullanmak library::abiverison129389123::fookirli görünecektir.
Bir güncelleme yapıldığında foo, yani sınıfa yeni bir üye eklendiğinde, zaten üyeyi kullanmayacakları için API düzeyinde mevcut programları etkilemez VE satır içi ad alanı adındaki değişiklik API düzeyinde hiçbir şey değiştirmez çünkü library::foohala çalışacak.
namespace library {
inline namespace abi_v2 {
class foo {
//new member
}
}
}
Bununla birlikte, onunla bağlantı kuran programlar için, satır içi ad alanı adı normal ad alanı gibi sembol adlarına karıştırıldığı için, değişiklik bağlayıcıya saydam olmaz. Bu nedenle, uygulama yeniden derlenmemişse ancak kitaplığın yeni bir sürümüyle abi_v1bağlantılıysa, ABI uyumsuzluğu nedeniyle çalışma zamanında gerçekte bağlanmak ve daha sonra gizemli bir mantık hatasına neden olmak yerine hata bulunmayan bir sembol sunar . Yeni bir üye eklemek, programı derleme zamanında etkilemese bile (API düzeyi) tür tanımındaki değişiklik nedeniyle ABI uyumluluğuna neden olur.
Bu senaryoda:
namespace library {
namespace abi_v1 {
class foo {
}
}
inline namespace abi_v2 {
class foo {
//new member
}
}
}
Satır içi 2 olmayan ad alanı kullanmak gibi, uygulamanın yeniden derlenmesine gerek kalmadan kütüphanenin yeni bir sürümünün bağlanmasına izin verir, çünkü abi_v1genel sembollerden birinde karıştırılır ve doğru (eski) tür tanımını kullanır. Ancak uygulamanın yeniden derlenmesi, başvuruların çözümlenmesine neden olur library::abi_v2.
Kullanmak using namespace, kullanmaktan daha az işlevseldir inline(hat dışı tanımlar çözülmez), ancak yukarıdaki ile aynı 4 avantajı sağlar. Ancak asıl soru, şimdi bunu yapmak için özel bir anahtar kelime olduğunda neden bir geçici çözüm kullanmaya devam etmektir. Daha iyi uygulama, daha az ayrıntılı (2 yerine 1 kod satırını değiştirmek zorunda) ve niyeti açıklığa kavuşturuyor.
using namespace V99;Stroustrup örneğinde neden çalışmadığını açıklayan +1 .