2011-06-09 81 views
5

如果我們有以下幾點:完美轉發

template <class T> 
struct B{ 
    T data; 
} 

struct A{ 
    int data_array[100]; 
} 

int main() 
{ 
    A x; 
    const A x_const; 

    auto y1 = f(A()); 
    auto y2 = f(x); 
    auto y3 = f(x_const); 
    auto y4 = f(std::move(x)); 
} 

我想知道的f(地起作用,但宏是好的,也是),使得:

decltype(y1) == B<A> 
decltype(y2) == B<A&> 
decltype(y3) == B<const A&> 
decltype(y4) == B<A&&> 

也就是說,f完全向前x轉換成B的對象。

+3

[What for?](http://www.catb.org/esr/faqs/smart-questions.html#goal) – GManNickG 2011-06-09 02:09:28

+0

您可以選擇函數重載作爲最後的手段。 :) – iammilind 2011-06-09 02:21:51

回答

3
template <typename T> 
auto f(T&& t) -> B<decltype(std::forward<T>(t))> 
{ 
    return B<decltype(std::forward<T>(t))>{std::forward<T>(t)}; 
} 

這確實幾乎你想要什麼。唯一的區別是第一個類型是B<A&&>而不是B<A>

8

這是不可能的。對於y1y4,則它們都採用類型A的右值,但您希望它們返回不同的類型。 f應該怎麼知道回報?

+1

好吧,'decltype(A())'是'A',但'decltype(std :: move(A()))'是'A &&',所以有一些區別。 – HighCommander4 2011-06-09 02:09:44

+2

@ HighCommander4:它們都是右值。沒有任何參考或其他語言結構可以區分A和未命名的A && - 事實上,這是您無法做到的一半。 – Puppy 2011-06-09 04:07:49

+5

@ HighCommander4問題的區別在於一個是一個prvalue,另一個是一個xvalue。由於參數傳遞僅允許區分左值和右值,因此實際上不可能檢測函數內部的差異(這是設計)。 – 2011-06-09 04:44:28

2
auto y1 = f(A()); 
auto y4 = f(std::move(x)); 

會不會區分,如A()產生一個臨時將結合到A&&