2011-08-03 110 views
5

從ISO C A點++草案(n3290):ISO C++草案 - 3.4.2/3 - 參數從屬名稱查找

3.4.2/3參數從屬名稱查找:

假設X是通過未經查詢的查找(3.4.1)和 產生的查找集合,讓Y爲由參數相關查找產生的查找集合 (定義如下)。如果X包含

  • 一個類的成員(#1)或
  • 一個塊範圍函數 聲明是不是使用聲明(#2)或
  • 聲明 即宣告功能或功能模板(#3)

然後Y爲空。否則,Y是在 中找到的與參數類型關聯的名稱空間的聲明集合,如下所述。 通過查找名稱找到的一組聲明是XY的聯合 。

是否有演示ADL涉及#1,#2和#3的示例代碼段?

回答

3

我認爲這段代碼涵蓋了所有的情況(也可在http://ideone.com/CbyJv)。如果你沒有在ideone中選擇C++ 0x,那麼允許情況2(但gcc 4.5.2捕獲它)。

#include <iostream> 

// ::f 
void f (int i) { std::cout << "::f\n" ; } 

// Simple case 
void OK1() { 
    f (99) ; // Calls ::f 
} 

// Argument-dependend lookup 
namespace MyNamespace { 
struct S { int i ; } ; 
void f (S& s) { std::cout << "MyNamespace::f\n" ; } 
} 

void OK2() { 
    MyNamespace::S s ; 
    f (99) ; // Calls ::f 
    f (s) ; // Calls MyNamespace::f because the type of s is declared in MyNamespace 
} 

// Declaration of a class member (#1) 
struct C { 
    static void ERROR1() { 
    MyNamespace::S s ; 
    f (s) ;  // Error: MyNamespace::f not matched, because Y is empty (#1) 
    } 
    static void f() { // Declaration of a class member (#1) 
    std::cout << "C::f\n" ; 
    } 
} ; 

// Block-scope function declaration (#2) 
void ERROR2() { 
    void f() ; // Block-scope function declaration (#2) 
    MyNamespace::S s ; 
    f (s) ; // Error: MyNamespace::f not matched, because Y is empty (#2) 
} 

// Declaration that is neither a function or a function template (#3) 
void ERROR3() { 
    MyNamespace::S s ; 
    f (s) ;   // OK: MyNamespace::f called 
    typedef int f[3] ; // Declaration that is neither a function or a function template (#3) 
    f (s) ;   // Error: MyNamespace::f not matched, because Y is empty (#3). This is an initialiser 
} 
1

數字1非常簡單 - 如果您在班級內尋找名稱N,並且班級中有成員N,就是這樣!你不必去其他地方看。

2號,我相信是相似的,但塊內部

{ 
    void f(double); 

    f(42); 
} 

代碼將嘗試調用函數f聲明那裏,如果可能的話,否則放棄。

3號再次類似。如果你尋找名字N並找到那個不是函數的名字,你不必去尋找重載。

0

對於它的價值,這也稱爲Koenig查找。我沒有所有3的例子,但博佩爾森已經提供了一些。