2011-06-09 5 views
5

parfait Si nous avons les éléments suivants:expédition

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

Je veux savoir une f (fonction de préférence, mais macro est correct aussi) tel que:

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

C'est, f parfaitement en avant x dans un objet de B.

+3

[Que faire?] (Http://www.catb.org/esr/faqs/smart-questions.html#goal) – GManNickG

+0

Vous pouvez choisir la surcharge de fonction en dernier recours. :) – iammilind

Répondre

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

Cela ne presque ce que vous voulez. La seule différence est pour le premier le type est B<A&&> plutôt que B<A>.

8

Ceci est impossible. Pour y1 et y4, ils prennent tous les deux des valeurs de type A, mais vous souhaitez qu'ils retournent des types différents. Comment devrait f savoir quoi retourner?

+1

Eh bien, 'decltype (A())' est 'A' mais' decltype (std :: move (A())) 'est' A && ', donc il y a une différence. – HighCommander4

+2

@ HighCommander4: Ils sont tous les deux des valeurs. Il n'y a pas de référence ou d'autre construction de langage qui puisse faire la distinction entre A et A && sans nom - en fait, c'est la moitié du point que vous ne pouvez pas. – Puppy

+5

@ HighCommander4 La différence en question est que l'un est un prvalue et l'autre est une valeur x. Puisque le passage d'argument ne permet de discriminer que les valeurs et les valeurs, il est en effet impossible de détecter la différence à l'intérieur d'une fonction (et c'est par conception). –

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

Ne sera pas se distinguer, comme A() produire un temporaire qui se liera à A&&.