2011-06-09 17 views
5

Si tenemos el siguiente:directa perfecta

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)); 
} 

Quiero saber un f (preferentemente la función, pero macro está bien también) tal que:

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

Es decir, f perfectamente hacia delante x en un objeto de B.

+3

[¿Para qué sirve?] (Http://www.catb.org/esr/faqs/smart-questions.html#goal) – GManNickG

+0

Puede elegir sobrecargar la función como último recurso. :) – iammilind

Respuesta

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)}; 
} 

Esto hace casi lo que quiere. La única diferencia es que para el primero el tipo es B<A&&> en lugar de B<A>.

8

Esto es imposible. Para y1 y y4, ambos toman rvalues ​​de tipo A, pero desea que devuelvan tipos diferentes. ¿Cómo debe saber f qué devolver?

+1

Bueno, 'decltype (A())' es ''A' pero' decltype (std :: move (A())) 'es' A && ', por lo que hay alguna diferencia. – HighCommander4

+2

@ HighCommander4: Ambos son valores. No hay referencia u otro constructo de lenguaje que pueda discriminar entre A y un A && sin nombre; de ​​hecho, es la mitad del punto que no puedes. – Puppy

+5

@ HighCommander4 La diferencia en cuestión es que uno es un valor prverente y el otro es un valor x. Como el paso de argumentos permite discriminar únicamente entre valores y valores, es imposible detectar la diferencia dentro de una función (y esto es por diseño). –

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

no será distinguible, como A() producen un temporal que se unirá a A&&.