大致順序是
編譯器執行以上步驟的時候是使用貪心匹配,只要找到乙個符合當前檢查內容的就會停止查
找所以任何一層都有可能發生錯誤的掩蓋情況
例1
void f( int ) {}
class y
y()} ;
這裡的f(2)在1.(2)這裡找到了符號f,就不會向上到1.(5)查詢到真正的f(int)了
例2
void g( int ) {}
namespace s
void h()
}
這裡的g(1)在1.(5)這裡找到了符號g,就不會向上到1.(6)查詢到真正的g(int)了
例3
class y
// [1]
public :
void f( double ) {} // [2]
} ;int main()
y.f(1)會呼叫[2]嗎?不會,因為在第2步過載決議的時候就選定[1]了,因此這段**會報
出無法訪問private成員的錯誤
例4
template < typename t >
void f(t) {} // [1]
template < typename t >
void f(t * ) {} // [2]
template <>
void f < int *> ( int * ) {} // [3]
int main()
這裡的f(p)會呼叫[3]嗎?
不會,因為在進行到第二步過載決議的時候,只有[1]和[2]參與了過載決議,結果選擇了
[2],那麼[1]的特化版本[3]當然就輪不到了。
例5
class x
public :
template <> void g < int > () {}
} ; int main()
這裡首先第3步訪問檢查發現g為private(此時g的特化版本被直接無視了),所以即使
g為public, 該段**仍然不能夠編譯通過
例6
namespace e
; void f(x) {} // [1]
} void f(e::x) {} // [2]
class x
// [3]
void g()
} ;
[4]會呼叫那個呢? 在1.(3)裡就確定了是[3],因此引數不匹配
如果注釋掉[3]的f,那麼由於koenig查詢, 在1.(5)裡[1]和[2]都會是平等的可選項
所以會出現二義性.
如果把namespace e改為class e, 把e中的f改為靜態函式
由於koenig查詢僅僅匯入引數的名字空間, 因此[1]將不參與1.(5)的查詢,
最終結果會是[2]
例7這是乙個現實中的例子,如果想給std::pair寫乙個ostream的輸出函式,應該如何實現呢?
templateostream& operator<
差不多該這樣吧
但是如下**就會導致出錯
mapa;
copy(m.begin(), m.end(), ostream_iterator>(s, "\n"));
為什麼呢?
因為在ostream_iterator的實現**裡呼叫了pair的operator<<
由於ostream_iterator的**是在std名字空間裡的,因此編譯器會首先在std裡查詢是否存在operator<<
一旦找到(儘管找到的operator《不是給pair使用的),就不會繼續到全域性名字空間裡查詢我們自己定義的operator《了
因此解決方案是把自定義的operator《放到std名字空間裡
namespace std
}
就可以了
例8傳說中的hide
struct a
};struct b: public a
};int main()
b.f(1)能編譯通過嗎?不能,因為編譯器會首先在b的名字空間裡查詢f,找到了void f(void),然後就會停止查詢
因此a裡的f(int)根本就沒有機會被編譯器訪問到
C 模板 名稱查詢
在編譯模板的時候,編譯器會分兩個階段去解析遇到的名稱,第乙個階段解析不依賴於模板引數的名稱,第二個階段解析依賴於模板引數的名稱,下面舉個簡單的例子來說明這一點 templateclass x typedef double e templateclass y public x 這個例子中定義了兩個類模...
Action名稱的搜尋順序
1 首先尋找namespace為 path1 path2 path3的package,如果存在這個package,則在這個package中尋找名字為test的action,如果不存在這個package則轉步驟3 2 尋找namespace為 path1 path2的package,如果存在這個pac...
查詢 順序查詢 C語言
順序查詢 sequential search 的查詢過程為 從表的一端開始,依次將表中的關鍵字和給定的值進行比較,若表中的關鍵字和給定的值相等,則查詢成功,反之查詢失敗。優點 演算法簡單,適用於順序結構和鏈式結構 缺點平均查詢長度較大,效率較低 順序查詢的優化 詳細見 普通優化 順序查詢 設定監視哨...