// Assuming the following:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
// or even using namespace std, though this
// would make std::swap a candidate even
// without ADL
// renaming shows that it's not this function
// that gets called ...
void myswap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
// printing some output also reveals what's going on
}
int main() {
string a{"sssss"}, b{"ddddd"};
swap(a,b); // this is not calling your swap!
// myswap(a,b) produces the error you expected
cout << a << ' '<< b <<endl;
return 0;
}
它沒有調用你的交換功能。命名空間是一種接口,所以當聲明自由函數與它們操作的數據類型在同一個命名空間中時,然後調用它們時沒有適當的名稱空間限定。
這被稱爲「參數相關名稱查找」或ADL。
因此,當您在std::string
上調用函數swap
時,它還會在std
名稱空間中查找候選項。並且由於std::swap
可以應用於字符串,並且不會在您的全局名稱空間中使用其他候選項(因爲您的交換隻能對整數進行操作),它將用於該調用。
正如我上面顯示你可以讓你的函數產生的調試輸出或重新命名它很容易驗證它不是你的函數被調用。
作爲一個方面說明:假設有某種從字符串到int的隱式轉換。你會得到兩個臨時工。然後你的交換函數會被調用(實際上不是,因爲binding non const references to temporaries isn't allowed)和這些整數交換。接着?這對原始字符串沒有任何影響。
最後,我不會將此代碼計算爲便攜式。它只在頭部字符串或iostream包含算法頭部時編譯,而這三者之一爲字符串提供了std :: swap的特化。但是由於這個標準似乎沒有保證,所以這個代碼只有在你自己包含算法時才能可靠地工作。
爲了驗證你的程序確實按照你的想法做了什麼,使你的'swap'函數打印一條消息。 –
要改善您的問題,請發佈提供問題的實際代碼。你顯然省略了一些線,也許認爲它們不重要。 –
感謝您的反饋意見。這真的很有幫助。我沒有預料到內置的交換功能會被調用。我按照@n.m的建議打印了一條消息。這證明我的交換沒有被調用。我曾經使用過「使用命名空間標準」,這是這裏的罪魁禍首。非常感謝!下次將包含完整的代碼。對不起, –