2011-08-10 74 views
4

從ISO C A點++草案(n3290):3.4.3.2/1命名空間的成員從ISO C A點++草案(n3290):3.4.3.2/1命名空間的成員

如果嵌套名-enable-id指定一個限定名稱空間, 在嵌套名稱說明符之後指定的名稱在 中查找名稱空間的範圍。 如果合格標識以::開頭,則::之後的 名稱將在全局名稱空間中查找。在 的情況下,模板ID的模板參數中的名稱在發生整個後綴表達式的上下文中查找 。

這裏任何一個可以對BOLD部分解釋....從早期的C++ 03草案的C++ 0x草案他補充說

如果一個合格的-ID開頭::,在::之後的名字在全局命名空間中查找到 。

任何一個可以用一個例子說明程序請

回答

5

::S是一個合格的-ID。

在合格代碼::S::f,S::是一個嵌套名稱說明符。

在非正式方面,嵌套的名稱說明符是

  • 無論是在合格-ID的開始或初步範圍解析運算符(之後開始的ID的一部分:如果:)一個出現在id的最開始處,並且
  • 以合格id中的最後一個作用域解析運算符結束。

非常非正式地,id是合格id或非限定id。如果id是一個限定標識符,它實際上由兩部分組成:一個嵌套名稱說明符,後跟一個非限定標識符。

考慮:

struct A { 
    struct B { 
     void F(); 
    }; 
}; 
  • A是不合格的-ID。
  • ::A是合格的id,但沒有嵌套名稱說明符。
  • A::B是一個限定符號,A::是一個嵌套名稱說明符。
  • ::A::B是限定符號,A::是嵌套名稱說明符。
  • A::B::F是限定符號,B::A::B::都是嵌套名稱說明符。
  • ::A::B::F是限定符號,B::A::B::是嵌套名稱說明符。

又如:

#include <iostream> 
using namespace std; 

int count(0);     // Used for iteration 

class outer { 
public: 
    static int count;   // counts the number of outer classes 
    class inner { 
    public: 
     static int count;  // counts the number of inner classes 
    }; 
}; 

int outer::count(42);   // assume there are 42 outer classes 
int outer::inner::count(32768); // assume there are 2^15 inner classes 
           // getting the hang of it? 

int main() { 
    // how do we access these numbers? 
    // 
    // using "count = ?" is quite ambiguous since we don't explicitly know which 
    // count we are referring to. 
    // 
    // Nested name specifiers help us out here 

    cout << ::count << endl;  // The iterator value 
    cout << outer::count << endl;   // the number of outer classes instantiated 
    cout << outer::inner::count << endl; // the number of inner classes instantiated 
    return 0; 
} 

編輯:

在回答您的意見,我認爲這種說法只是意味着一個模板的參數進行處理WRT通過上下文和線他們被宣佈。例如,

f.~foo();,富時擡頭內f.,和foo<int>範圍內,它是有效的參考,它只是與foo

+0

這部分怎麼樣「n無論哪種情況,模板id的模板參數中的名稱都會在發生整個postfix-expression的上下文中查找。 ...請說明這一點 – user751747

+0

@user:看我的編輯。 – 2011-08-10 07:12:34

5

它被稱爲限定名稱查找
領先的::引用全局名稱空間。以::開頭的任何合格標識符將始終在全局名稱空間中引用局部命名空間中相同命名標識符中的某個標識符。

namespace A 
{ 
    namespace B 
    { 
     void doSomething(); 
    } 
} 

namespace Z 
{ 
    namespace A 
    { 
     namespace B 
     { 
      void doSomething(); 
     } 
    } 

    using namespace A::B // no leading :: refers to local namespace layer 

    void doSomethingMore() 
    { 
     doSomething(); // calls Z::A::B::doSomething(); 

    } 
} 

namespace Z 
{ 
    namespace A 
    { 
     namespace B 
     { 
      void doSomething(); 
     } 
    } 

    using namespace ::A::B // leading :: refers to global namespace A 
    void doSomethingMore() 
    { 
     doSomething(); // calls ::A::B::doSomething(); 
    } 
} 
+0

恐怕這不是答案 - >「任何一個_explain_都可以用示例程序」 –

+0

@phresnel:不要害怕,現在它是一個答案:) –

+0

+1這裏是我的upvote。 – 2011-08-10 07:14:44

2

加粗的文字是指兩種不同的情況。第一部分是使用或不使用::作爲前綴的區別。當一名合格的名稱與::啓動確切的命名空間檢查從空命名空間開始,而如果它不存在,搜索將考慮嵌套的命名空間:

namespace A { 
    void f() { std::cout << "::A::f" << std::endl; } 
} 
namespace B { 
    namespace A { 
     void f() { std::cout << "::B::A::f" << std::endl; } 
    } 
    void g() { 
     A::f();  // ::B::A::f 
     ::A::f(); // ::A::f 
    } 
} 

段落中的最後一句是指在特定的模板參數,它告訴你的是,查找將不會在該模板聲明的名稱空間開始,而是在它被實例化的命名空間:

struct A { 
    static void f() { std::cout << "::A::f()" << std::endl; } 
}; 
template <typename T> 
void f() { 
    T::f(); 
} 
namespace N { 
    struct A { 
     static void f() { std::cout << "::N::A::f()" << std::endl; } 
    }; 
    void g() { 
     f<A>(); 
    } 
} 

如果查找模板命名空間開始,呼叫f<A>()將參考f<::A>,但標準中的該子句將在名稱空間N,其中整個後綴表達式出現在)內開始查找,因此將調用::N::A::f()

0
int a(1); 

class someCls { 
    private: 
    int a; 
    public: 
    // Assigns this->a with the value of the global variable ::a. 
    void assignFromGlobal() { 
     a = ::a; 
    } 
};