2016-01-04 54 views
1

我的問題很簡單。執行以下操作是否安全?是否在名稱空間foo中聲明swap(),然後在同一名稱空間下使用swap()而不是foo :: swap()意味着foo :: swap()?

不需要任何倫理建議,如「不要對你的功能互換()!」或別的,請!

file1.hpp

//header guards here 
#include <utility> //includes std::swap and std::move 

namespace foo 
{ 
    template<typename T> 
    inline void swap(T& lhs, T& rhs) 
    { 
     T temp = std::move(lhs); 
     lhs = std::move(rhs); 
     rhs = std::move(temp); 
    } 
} 

file2.cpp

#include "file1.hpp" 

namespace foo 
{ 
    template<typename T> 
    void myfun(T a, T b) 
    { 
     a += b; 
     swap(a, b); //does it imply foo::swap, because the function 
        //is declared in the foo namespace?? 
    } 

} 
+0

參數依賴查找不會有任何效果,你的模板是太貪婪。 –

+0

@DieterLucking你說我應該說使用foo :: swap;在功能上讓它更慈善? – DeiDei

+1

你爲什麼不簡單地用'std :: cout <<「Hello world」'語句來測試它? –

回答

4

這一切都取決於T類型。

如果T的類型位於具有自己的交換的不同名稱空間中,則依賴於參數的查找將找到不同的swap()。否則,它會查看當前的命名空間。

#include <utility> //includes std::swap and std::move 
#include <iostream> 

namespace foo 
{ 
    template<typename T> 
    inline void swap(T& lhs, T& rhs) { 
     std::cout << "foo swap\n"; 
    } 
} 
namespace foo 
{ 
    template<typename T> 
    void myfun(T a, T b) 
    { 
     a += b; 
     swap(a, b); // Looks for swap using the type T. 
        // If not found uses the current namespace. 
        // If not found uses the enclosing namespace. 
    } 

} 

namespace baz 
{ 
    class X { 
     public: 
     X& operator+=(X const& rhs){return *this;} 
    }; 
    inline void swap(X& lhs, X& rhs) { 
     std::cout << "Bazz Swap\n"; 
    } 
} 

int main() 
{ 
    baz::X a,b; 
    foo::myfun(a,b); // finds ::baz::swap() 
} 

結果:

> a.out 
Bazz Swap 
> 
+0

正如我有一個例子編譯並準備顯示這個答案被張貼。 – SergeyA

2

它將調用foo::swap
你可以使用std::swap(a, b);如果你想使用std實施

2

是的,當然。首先搜索當前命名空間的非限定名稱。

1

它將調用foo::swap()。有一個常見的成語,這是寫

using std::swap; 
swap(x, y); 

在通用代碼。這使得std::swap實施奏效。但是,它也需要swap()功能考慮它們在其他命名空間通過參數相關的查找(ADL)找到。所以如果有函數foo::swapxy的類型在namespace foo中,那麼將調用這個foo::swap,如果它比std::swap更好的匹配。