2012-05-01 13 views
7

Ad alanı içinde işlev yapmamalı, yalnızca ad alanı kapsamı kullanılarak veya kullanma yönergesiyle erişilebilir olmalıdır?Neden ad alanı kapsamı öneki olmadan bir ad alanında bazı işlevler kullanılabilir?

Ad alanı içinde tanımlanmış bazı işlevlerin söz konusu ad alanının DIŞINDAN erişilebilir olduğu bir sorun yaşıyorum. Derleyici bir hata olması gerektiğine inanıyorum, ama denediğim üç farklı derleyicide bir tane almıyorum (VS.NET 2003, VS2010 ve GCC 4). fonksiyonların

namespace N{ 
    typedef struct _some_type *some_type; 
    struct some_struct { int x; }; 
    void A(void); 
    void B(int); 
    void C(some_type*); 
    void D(some_type); 
    void E(struct some_struct); 
} 

using N::some_type; 
using N::some_struct; 

void TestFunction() 
{ 
    some_type foo; 
    some_struct s; 

    N::A();   //should compile (and does on VS2003, VS2010, and GCC 4.1.2) 
    ::A();   //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 
    A();   //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 

    N::B(0);  //should compile (and does on VS2003, VS2010, and GCC 4.1.2) 
    ::B(0);   //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 
    B(0);   //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 

    N::C(&foo);  //should compile (and does on VS2003, VS2010, and GCC 4.1.2) 
    ::C(&foo);  //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 
    C(&foo);  //shouldn't compile (but does on VS2003, VS2010, and GCC 4.1.2) -- problem! 

    N::D(foo);  //should compile (and does on VS2003, VS2010, and GCC 4.1.2) 
    ::D(foo);  //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 
    D(foo);   //shouldn't compile (but does on VS2003, VS2010, and GCC 4.1.2) -- problem! 

    N::E(s);  //should compile (and does on VS2003, VS2010, and GCC 4.1.2) 
    ::E(s);   //shouldn't compile (and doesn't on VS2003, VS2010, and GCC 4.1.2) 
    E(s);   //shouldn't compile (but does on VS2003, VS2010, and GCC 4.1.2) -- problem! 
} 

Yok Yok :: öneki kullanmadan erişilebilir olmalı, ama C, D ve E bilinmeyen bir nedenle şunlardır: Burada

kodudur. Başlangıçta derleyici bir hata olduğunu düşündüm, fakat bunu birden çok derleyicide görüyorum çünkü bana neler olduğunu sorguluyor.

+0

Bunun bir "eski derleyici hata" olduğunu sanıyordum, ama aynı zamanda gcc 4.6'yı derliyor. – mfontanini

+0

En iyi tahminim şu satırlara sahip olmanızdır: 'N: some_type; 've' N: some_struct;' kullanarak ve C, D ve E dönüş türleri bu tiplerdir. – gcochard

+0

Greg, bunları kaldırabilirsiniz ve hala gerçekleşir. Ayrıca tüm fonksiyonların dönüş tipleri geçersizdir. – syplex

cevap

10

Sanırım Koenig lookup'un etkisini görüyorsunuz. Örneğinizde foo ve s, N ad alanında tanımlanan türleridir. C, D ve E rutinlerine yapılan çağrılarınız bu tür argümanları kullanır, bu nedenle bu işlev çağrılarını çözmek için isim alanı N aranır.

+3

Yan nota: Parantez ekleme, yani '(C) (& foo)', argüman bağımlı aramayı engeller. –

+0

Eh, siz haklısınız. 2003 C++ spesifikasyonunun 3.4.2 bölümünde yer almaktadır. Spekülasyonun bu kısmına katılmıyorum ve kötü düşünülmüş olduğunu düşünüyorum ama var. GCC veya VC++'da daha sıkı bir ad alanı kapsamını zorlamak için bir yol olup olmadığını bilen var mı? – syplex

+0

@syplex Aslında, şablonlar içindeki argüman türlerine dayanarak serbest fonksiyonları düzgün şekilde aramak son derece kullanışlıdır. Ben g ++ standart tarafından gerekli olana karşı gitmek gibi bir seçenek sunuyor sanmıyorum. Burada çözmeye çalıştığınız * gerçek * problem nedir? –