如果你有這個功能完美轉發在C++ 03
template<typename T> f(T&);
,然後嘗試調用它,比方說像
f(1);
爲什麼右值不是T只是推斷爲const int,使參數爲const int &並因此可綁定到右值?
如果你有這個功能完美轉發在C++ 03
template<typename T> f(T&);
,然後嘗試調用它,比方說像
f(1);
爲什麼右值不是T只是推斷爲const int,使參數爲const int &並因此可綁定到右值?
這被提及爲the document中的一個潛在解決方案,我在recent C++0x forwarding question中鏈接了我。
它會工作得很好,但它破壞了現有的代碼。考慮(直接從文件):
template<class A1> void f(A1 & a1)
{
std::cout << 1 << std::endl;
}
void f(long const &)
{
std::cout << 2 << std::endl;
}
int main()
{
f(5); // prints 2 under the current rules, 1 after the change
int const n(5);
f(n); // 1 in both cases
}
或者
// helper function in a header
template<class T> void something(T & t) // #1
{
t.something();
}
// source
#include <vector>
void something(bool) // #2
{
}
int main()
{
std::vector<bool> v(5);
// resolves to #2 under the current rules, #1 after the change
something(v[0]);
}
這也無法轉發的價值類別(左值或右值),這是沒有太大的C++ 03的問題。但由於此修復只能在C++ 0x期間完成,因此在轉發時(壞事情),我們會有效地將自己從rvalue引用中關閉。我們應該爭取更好的解決方案。
這是,但只有當你宣佈f
採取T const &
。
template <typename T> void f(T &);
template <typename T> void g(T const &);
void x() { f(1); } // error: invalid initialization of non-const reference
void y() { g(1); } // no error
如果你聲明都f(T &)
和f(T const &)
,它會選擇const限定一個:
template <typename T> void f(T &);
template <typename T> void f(T const &);
void x() { f(1); } // no error, calls f(T const &)
現在,也許你說「在第一個例子,爲什麼它生成一個int
類型的臨時文件f
,當它可能已經生成了const int
類型的臨時文件,並使代碼編譯? 」我給你的最佳答案是,當參數不是整數常量時,這與重載解析行爲不一致。
是的,我知道超載。我想知道爲什麼甚至有必要。它會如何不一致? – Puppy 2010-08-28 18:16:20
@DeadMG:'1'的類型爲'int'。如果你聲明瞭一個'int i = 1',那麼它會選擇非const方法,因爲'i'不是const。因此,爲了一致性,它也是這樣,除了對於右值而言,這是一個錯誤。 – 2010-08-29 11:13:54
@Matthieu:1是一個int rvalue。我是一個整數左值。由於語言堅持以不同的方式對待他們,所以他們是不同的東西。因此,這並不矛盾。事實上,有一些專門針對右值的規則是不一致的,然後在這裏嘗試對待它們。 – Puppy 2010-08-29 11:28:53