2017-06-23 3 views
1

Mon objectif est de faire une fonction qui prend fonction et une liste d'arguments et renvoie cette signature de fonction. Cela semble simple au début, mais l'utilisation principale serait d'aider à reconnaître quelle fonction la surcharge a été choisie pour des arguments spécifiques et les modèles ne sont pas utiles pour moi ici. J'ai déjà trouvé du code sur la pile qui me permet d'imprimer le type de n'importe quelle variable, mais obtenir un pointeur vers la surcharge correspondante est une autre histoire. Ma première tentative était la suivante:Obtenir la surcharge correspondant en fonction des types d'argument

template<typename F, typename... Args> 
auto sig(F f, Args... args) -> decltype(f(std::forward<Args>(args)...), void()) { 
    std::cout << get_name<decltype(f)>() << '\n'; 
} 

Et ça marche ... aussi longtemps que la fonction n'a pas de surcharge. Par exemple:

void foo(bool) {} 
void fun(double&&) {} 
void fun(int&&) {} 

Avec ces fonctions, je peux faire

sig(foo, true); 

mais pas

sig(fun, 5.5); 

Après quelques googler, je suis venu avec

template<typename... A> 
using sign = decltype(fun(std::declval<A>()...))(*)(A...); 

Il nécessite des macros à travailler avec n'importe quelle fonction (le plaisir est ha codé pour l'instant), mais c'est ok. Le problème est que, fondamentalement, il vérifie seulement s'il y a une surcharge correspondante et que la signature retournée n'est correcte que sur le type de retour.

À ce stade, je suis tout à fait à perdre ce qu'il faut essayer ensuite et mon google-fu échoue. J'apprécierais de l'aide avec ça. Here is link to wandbox if anyone wants to play with what is already done.

Répondre

1
#define RETURNS(...) \ 
    noexcept(noexcept(__VA_ARGS__)) \ 
    -> decltype(__VA_ARGS__) \ 
    { return __VA_ARGS__; } 

#define OVERLOADS_OF(...) \ 
    [](auto&&...args) \ 
    RETURNS(__VA_ARGS__(decltype(args)(args)...) 

Maintenant,

sig(OVERLOADS_OF(fun), 5.5); 

fait ce que vous voulez.

Il y a un post-C++17 proposal pour simplifier à

#define OVERLOADS_OF(...) \ 
    [](auto&&...args) => __VA_ARGS__(decltype(args)(args)...) 

ou

sig([](auto&&x)=>fun(decltype(x)(x)), 5.5); 

ou même des variantes briefer.

+0

Pouvez-vous poster un lien vers la proposition? Juste curieux. Je vous remercie. – skypjack

+1

@skyp lié ci-dessus. – Yakk

+0

Merci pour la réponse! Ce que vous m'avez donné me permet de créer un proxy pour la surcharge de fonction et permet d'appeler le signal - c'est cool, je ne savais pas que cela pouvait être fait de cette façon. Cependant appeler 'sig (OVERLOADS_OF (fun), 5.5);' sous gcc imprime 'main() :: ' donc je suis toujours parti sans information quelle surcharge a été choisie - en particulier quel genre des arguments qu'il a déclaré accepter - et c'est ce que je suis après. – Stoic