2011-03-22 36 views
5

這似乎有點倒退到我,但它的工作原理:爲什麼C++參數範圍影響名稱空間內的函數查找?

#include <iostream> 

namespace nTest 
{ 
    struct cTest {}; 

    void fTest(cTest& x) 
    { 
    std::cout << "nTest::fTest(cTest&) called" << std::endl; 
    } 
} 

int main(void) 
{ 
    nTest::cTest x; 
    fTest(x); //Weird! fTest is resolved since its parameter belongs to nTest. 
    return 0; 
} 

通常情況下,你需要NTEST ::才能訪問FTEST,但屬於NTEST它的參數似乎NTEST增加的可能名單在其中搜索fTest的範圍。對我來說,參數範圍影響函數查找似乎很奇怪。

這在GCC中編譯得很好,但我想知道這種用法是否便攜?這個範圍界定機制的官方定義是什麼?

+2

ADL - 參數依賴查找(http://en.wikipedia.org/wiki/Argument-dependent_name_lookup) – Nim 2011-03-22 14:21:20

+2

也讀取接受的答案[here](http://stackoverflow.com/questions/2958648/what-are -the-pitfalls-of-adl) – 2011-03-22 14:23:24

回答

1

它的最初目的是找到重載運算符,如操作員< <用於發送一個字符串到std ::法院。如果我們沒有ADL,那麼您將不得不像這樣編寫代碼:std::operator<<(std::cout, "nTest::fTest(cTest&) called")

不太好!

如果它適用於運營商,爲什麼不以同樣的方式工作?

12

這是ADL(參數從屬查找)或Koenig查找(用於該功能的設計者)。該功能的用途是,在許多情況下,相同的名稱空間將包含可應用於這些類型的類型和功能,所有這些類型和功能都符合interface。如果ADL不在位,則必須使用using聲明將標識符帶入範圍,否則您必須限定呼叫。

由於語言允許操作符重載,這成爲一場噩夢。請看下面的例子:

namespace n { 
    struct test {}; 
    test operator+(test, test const &); // implemented 
}; 
int main() { 
    n::test a,b; 
    n::test c = a + b; //without ADL: c = n::operator+(a, b) 
} 

雖然它看起來像一個尷尬的局面,考慮到n可能是std命名空間,test可能是ostream,並operator+可能是operator<<

int main(int argc, char**) { 
    std::cout << "Hi there, there are " << argc << " arguments" << std::endl; 
} 

沒有ADL ,operator<<的調用必須是明確的,而且您必須知道其中哪些實現爲自由函數與方法。您是否知道std::cout << "Hi"正在呼叫免費功能,並且std::cout << 5正在呼叫成員功能?沒有多少人意識到這一點,嚴肅地說,幾乎沒有人關心。 ADL隱藏了你的信息。

相關問題