2011-05-18 136 views
2

傳遞引用函數如何區分傳遞值函數?例如:區分傳遞引用和傳遞值

template <typename T> 
void sort(std::vector<T>& source); // Sorts source. 

// Versus... 

template <typename T> 
std::vector<T> sort(std::vector<T> source); // Returns a sorted copy of source. 

這兩個函數是不明確的;其中一個必須重新命名或完全刪除。

如何避免這種情況?一種形式是否應該優先於其他形式?或者是否有任何通用的命名指南來區分它們?

+1

爲什麼這是一個需要解決的問題?由於它們不明確,編譯器不會允許它們共存,因此只要運行編譯器,問題就會持續下去,之後程序員將撤銷先前的更改。 – 2011-05-18 17:07:44

+0

這是一個關於函數簽名的問題。如果第二個聲明通過'const'引用傳遞,則編譯器可以區分簽名。 – 2011-05-18 17:11:55

+0

是否真的不可能在調用時區分OP問題中的兩個函數?如果是的話,如果沒有,如果C++編譯器提供了一個錯誤,即使函數沒有被調用,它也不會是稍微好一點的行爲嗎?我可以在沒有調用的情況下使用gcc 4.6.3進行編譯。 – 2013-01-08 17:34:46

回答

6

難道你不能給他們不同的名字嗎?例如,我會命名功能版本sorted

只是因爲你可以重載函數(或函數模板在這種情況下)並不意味着你來。

順便說一句,你可以實現的「勢在必行版」術語「功能版本」:

template <typename T> 
void sort(std::vector<T>& source) 
{ 
    // sort in place 
} 

template <typename T> 
std::vector<T> sorted(std::vector<T> copy) 
{ 
    sort(copy); 
    return copy; 
} 
+5

「僅僅因爲你可以超載並不意味着你應該」是黃金。 – 2011-05-18 17:03:19

0

它通常傾向於不通過非const引用如果可能的話,並使用第二通形成。這是因爲首先,如果要將返回值傳遞給另一個函數,則第二類播放會更好,其次,因爲編譯器的優化器將在大多數情況下處理不必要的複製;第三,因爲有參考可以防止任何類型的TMP檢測到它實際上是一個返回值,並阻止在任何類型的函數對象上下文中使用該函數。

+0

Downvoter評論? – GManNickG 2011-05-18 19:34:02

+1

@GMan:不是我的downvote,但1)「防止在任何類型的函數對象上下文中使用函數」是錯誤的(例如std :: for_each),2)典型的使用名爲sort的函數(例如std :: sort,boost :: sort)是引用語義而不是價值語義,3)並沒有解決有利於模糊泛型建議的問題,而這些建議又與「排序」約定背道而馳。似乎這應該是一個評論。 – 2011-05-19 01:41:28

2

FredOverflow擊中了頭部。但是,要回答你的問題「或者是否有任何通用的命名指南來區分它們?」只要確保你是一致的。例如你的例子中的第二個函數名稱就像SortCopy。 SortCopy,SortCpy,Sort_Copy無關緊要。重要的是,在整個代碼中,你是一致的(例如,所有作用於副本的函數都有「Copy」前綴 - 沒有一個具有Copy,下一個Cpy等)。

+2

+1就是C++庫所做的事情:'std :: reverse()'/'std :: reverse_copy()','std :: remove_if()'/'std :: remove_copy_if()'boost boost'boost :: to_lower()'/'的boost :: to_lower_copy()' – Cubbi 2011-05-18 17:55:33