其實,這是一個非常好的問題。到目前爲止,我還一直在使用通用參考技巧加上enable_if
錘子。在這裏,我提出了一個不使用模板並使用左值轉換作爲替代方案的解決方案。
下面是其中的情況出現使用就地ofstream
使用已知的例子是不可能的(或很難)在C++ 98的真實例子(我用ostringstream
在這個例子中,以使其更清晰)。
首先,您將在C++ 98中看到一個關於左值引用的函數。
#include<iostream>
#include<sstream>
struct A{int impl_;};
std::ostringstream& operator<<(std::ostringstream& oss, A const& a){
oss << "A(" << a.impl_ << ")"; // possibly much longer code.
return oss;
}
// naive C++11 rvalue overload without using templates
std::ostringstream& operator<<(std::ostringstream&& oss, A const& a){
oss << "A(" << a.impl_ << ")"; // ok, but there is code repetition.
return oss;
}
int main() {
A a{2};
{// C++98 way
std::ostringstream oss;
oss << a;
std::cout << oss.str() << std::endl; // prints "A(2)", ok"
}
{// possible with C++11, because of the rvalue overload
std::cout << (std::ostringstream() << a).str() << std::endl; //prints "A(2)", ok
}
}
正如您在C++ 11中看到的,我們可以實現我們在C++ 98中無法實現的功能。那就是利用ostringstream
(或ofstream
)就地。現在出現OP問題,兩個重載看起來非常相似,都可以加入一個?
一種選擇是使用通用參考(Ostream&&
),並且可選地使用enable_if
來限制類型。不是很優雅。
我發現通過使用這個「真實世界」的例子是,如果想要使用相同的代碼左值參考和右值ref是因爲可能你可以將一個轉換爲另一個!
std::ostringstream& operator<<(std::ostringstream&& oss, A const& a){
return operator<<(oss, a);
}
這看起來像一個無限遞歸函數,但它不是因爲oss
是一個左值引用(是的,它是一個左值引用,因爲它有一個名字)。所以它會調用其他的超載。
您仍然需要編寫兩個函數,但其中一個代碼不需要維護。總之,如果「有意義」將函數同時應用於(非常量)左值引用和右值,這也意味着您可以將右值轉換爲左值並因此轉發給單個函數。請注意,「它有意義」取決於上下文和預期代碼的含義,而且我們必須通過明確地調用左值過載來「告知」編譯器。
我並不是說這比使用通用參考更好,我認爲它是一種替代方法,可以證明其意圖更加清晰。
可編輯代碼:http://ideone.com/XSxsvY。 (歡迎反饋)
rvalue傳遞簡單類型如'int'沒有意義。在更一般的情況下,我相信C++ 11有一個特殊情況,其中右值參數將被讀作右值或左值參數。儘管如此,我不記得確切的情況。 – Dave 2013-05-04 16:38:40
所以你希望'x'是一個右值引用(如果通過右值引用)或左值引用給'const'?我是否正確理解,X &&不會被你接受,因爲當左值被傳遞時,它將是對非''constst'的左值引用? – 2013-05-04 16:41:22
嗯,我們走吧,我相信你正在努力做到這一點:http://thbecker.net/articles/rvalue_references/section_07.html這是在下一頁使用rvalues解釋。如果我誤解了這個問題,大叫大叫。 – Dave 2013-05-04 16:41:40