我一直在切換Template Factory函數以使用(並理解)std :: forward來支持右值並移動語義。我通常用於模板類的樣板工廠函數始終將參數標記爲const:您是否曾將C++ RValue引用參數標記爲const
#include <iostream>
#include <utility>
template<typename T, typename U>
struct MyPair{
MyPair(const T& t, const U& u):t(t),u(u){};
T t;
U u;
};
template<typename T, typename U>
std::ostream& operator<<(std::ostream& os, const MyPair<T,U>& pair){
os << "(" << pair.t << ")=>" << pair.u;
return os;
}
template<typename T, typename U>
MyPair<T,U> MakeMyPair(const T& t, const U& u){
return MyPair<T,U>(t,u);
}
using namespace std;
int main(int argc, char *argv[]) {
auto no_forward = MakeMyPair(num, num);
std::cout << no_forward << std::endl;
auto no_forward2 = MakeMyPair(100, false);
std::cout << no_forward2 << std::endl;
}
按預期進行編譯。起初我轉換MakeMyPair也傳遞的參數爲const,但使用的XCode 4.6,這將不會在我的Mac編譯:
//$ clang --version
//Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
//Target: x86_64-apple-darwin12.2.0
//Thread model: posix
template<typename T, typename U>
MyPair<T,U> MakeMyPair_Forward(const T&& t, const U&& u){
return MyPair<T,U>(std::forward<const T>(t),std::forward<const U>(u));
}
int main(int argc, char *argv[]) {
int num = 37;
auto anotherPair = MakeMyPair_Forward(num, true); //This won't work
auto allRvalues = MakeMyPair_Forward(73, false); //will compile
std::cout << allRvalues << std::endl;
}
沒有匹配的功能調用「MakeMyPair_Forward」候補 函數[與T = INT ,U =布爾]不可行:爲第一參數從 「INT」沒有已知的轉換爲「const int的& &」
這使得從http://en.cppreference.com/w/cpp/utility/forward感其中規定常數推導並我傳遞左值。
- 如果到包裝器()的調用傳遞右值的std :: string,則T被推斷爲的std :: string(未的std :: string &,常量的std :: string &,或 性病:: string & &),並且std :: forward確保傳遞給foo的右值引用是 。
- 如果對wrapper()的調用傳遞const lvalue std :: string,則T推導爲const std :: string &,而std :: forward確保將const 左值引用傳遞給foo。
- 如果對wrapper()的調用傳遞一個非const的左值std :: string,則T被推斷爲std :: string &,而std :: forward確保將一個非const的 左值引用傳遞給foo 。
刪除const工程,因爲我想用rvalues和左值。只有傳遞rvalues作爲類型才能在MakeMyPair_Forward的參數上使用const。
//This works for rvalues and lvalues
template<typename T, typename U>
MyPair<T,U> MakeMyPair_Forward(T&& t, U&& u){
return MyPair<T,U>(std::forward<const T>(t),std::forward<const U>(u));
}
所以,這個問題。當作爲參數傳遞時,將右值引用標記爲const是否有意義?這不像我可以改變一個右值,這只是暫時的。通過修復和修復我的代碼後,我對編譯const的代碼感到有些驚訝。你爲什麼要將右值參數標記爲const?重點是隻提供一個需要rvalues的API嗎?如果是這樣,你會不會使用類型特徵來防止左值引用? https://stackoverflow.com/a/7863645/620304
謝謝。
如果您不想修改它,那麼它是否是暫時的並不重要。 –
我的想法是你不能修改它,因爲它是暫時的。所以標記爲const對我來說並不合適。 – Joel
爲什麼你不能修改臨時? –