2017-06-16 3 views
0

Je me demandais s'il existe une solution pour spécifier un modèle afin que void ou tout autre type puisse être passé. Voici un exemple très simplifié, qui ne devrait rien faire d'autre que renvoyer void si TReturn est également void, ou renvoyer la valeur de retour de la fonction (qui renvoie également TReturn, mais avec la différence, il s'agit alors d'un type) .C++ void ou tout type en tant que paramètre de modèle

template <typename TReturn> 
TReturn Foo(std::function<TReturn()> function) 
{ 
    if(std::is_same<TReturn, void>::value) 
    {   
     // I am not sure what to put here 
     return function(); 
    } 

    TReturn returnValue = function(); 
    // Do some stuff with the returnValue here 
    return returnValue; 
} 

Maintenant, évidemment, ce que j'ai fait est faux, car une fonction ne peut retourner deux types différents. C'est pourquoi je demande, est-ce que quelqu'un sait comment faire cela?

Toute aide est appréciée avec plaisir

+1

La mauvaise chose ici est que vous supposiez 'TReturn' être constructible par défaut (ce qui n'est pas le cas de' void'). Sinon, ça me semble ok. – davidhigh

+0

Un autre problème est que vous essayez de générer 'return void' au lieu de 'return' –

+0

@ManishBaphna oui, je sais que c'est faux c'est pourquoi je cherchais un moyen de rendre cette déclaration vraie pour les types non-'void' et en trouver un autre pour 'void' –

Répondre

8

Vous pouvez utiliser la surcharge:

template <typename TReturn> 
TReturn Foo(std::function<TReturn()> function) 
{ 
    TReturn returnValue = function(); 
    // Do extra stuff with return value. 
    return returnValue; 
} 

void Foo(std::function<void()>) 
{ 
    return function(); 
} 

En C++ 17, vous aurez constexpr si

template <typename TReturn> 
TReturn Foo(std::function<TReturn()> function) 
{ 
    if constexpr (std::is_same<TReturn, void>::value) { 
     return function(); 
    } else { 
     TReturn returnValue = function(); 
     // Do extra stuff with return value. 
     return returnValue; 
    } 
} 
+0

je vous remercie pour cela, je suis également venu avec cela, mais je pensais peut-être qu'il y aurait une solution avec une seule fonction. Si ce n'est pas le cas, je vais utiliser le vôtre, merci –

2

solution C++ 17:

template <typename TReturn> 
TReturn Foo(std::function<TReturn()> function) 
{ 
    if constexpr (std::is_same<TReturn, void>::value) 
//  ^^^^^^^^^ 
    {   
     return function(); 
    } else { 
     TReturn returnValue = function(); 
     return returnValue; 
    } 
} 

Sinon, si vous voulez la décision de retourner une valeur ou ne pas être faite au moment de la compilation, AFAIK vous allez avoir besoin de deux fonctions différentes (comme suggéré dans l'autre réponse).

+0

merci, je suis vraiment impatient de pouvoir l'utiliser en C++ 17. Cela semble beaucoup plus facile à utiliser. –