2010-04-22 4 views
3

C# a types de fonctions génériques tels que Action<T> ou Func<T,U,V,...>C# le style d'action <T>, Func <T,T>, etc en C++ 0x

Avec l'avènement de C++ 0x et la possibilité d'avoir du modèle de typedef et paramètres du modèle variadique , il semble que cela devrait être possible.

La solution évidente pour moi serait:

template <typename T> 
using Action<T> = void (*)(T); 

cependant, cela ne peut pas accueillir de foncteurs ou C++ 0x lambdas, et au-delà, ne compile pas avec l'erreur "expected unqualified-id before 'using'"

Ma prochaine tentative était peut-être utiliser la fonction boost :::

template <typename T> 
using Action<T> = boost::function<void (T)>; 

Cela ne compile pas non plus, pour la même raison.

Mon seul autre idée serait des arguments de modèle de style STL:

template <typename T, typename Action> 
void foo(T value, Action f) { 
    f(value); 
} 

Mais cela ne fournit pas une solution fortement typé et n'est pertinente dans la fonction basé sur un modèle.

Maintenant, je serai le premier à admettre que je ne suis pas le C++ wiz que je préfère penser que je suis, il est donc très possible qu'il y ait une solution évidente que je ne vois pas.

Est-il possible d'avoir des types de fonctions génériques de style C# en C++?

+0

Non, ce n'est pas possible. Pas assez. Ce sont des langues différentes. La question est de savoir quelle est l'approximation la plus proche, * en fonction de vos besoins *. Avez-vous besoin d'un effacement de type, de sorte que chaque foncteur ayant la même signature apparaît comme le même type? Si c'est le cas, vous devrez passer à travers des cerceaux, et perdre de l'efficacité. Et souvent, cela n'en vaut pas la peine, car en raison des différences entre les modèles et les génériques, ce n'est souvent pas * nécessaire *. Souvent, mais pas toujours. De quoi avez-vous besoin exactement? Autre que d'essayer aveuglément d'émuler C# en C++ – jalf

Répondre

6

Je pense que la syntaxe devrait être comme ceci:

template <typename T> 
using Action = void (*)(T); 

Je ne pouvais pas que pour compiler soit, bien que (g v4.3.2 de ++). Le modèle de fonction de style STL général n'est pas fortement typé au sens strict, mais il est de type sécurisé dans le sens où le compilateur veillera à ce que le modèle ne soit instancié que pour les types qui remplissent toutes les exigences de la fonction. Plus précisément, il s'agira d'une erreur de compilation si le Action n'est pas appelable avec un paramètre de type T. C'est une approche très flexible car peu importe si Action est instancié pour être une fonction ou une classe qui implémente operator().

L'ancienne solution non-C++ 0x pour le manque typedef serait basé sur un modèle d'utiliser une struct avec un typedef basé sur un modèle imbriqué:

template <typename T> 
struct Action { 
    typedef boost::function<void (T)> type; 
}; 

template <typename T> 
void foo(T value, typename Action<T>::type f) { 
    f(value); 
} 
1

gcc ne supporte pas les alias encore modèle (voir here), et je ne suis pas sûr si l'alias de modèle variadic est considéré. Je ne pense pas que d'autres compilateurs supportent déjà cette fonctionnalité.

Je vais simplement utiliser std :: function ou std :: function au lieu de Action ou Func.

Bien sûr, vous pouvez définir des classes de modèles variadiques Action ou Func à partir de std :: function mais je ne vois pas le bénéfice.

1

Je ne pense pas qu'un type de fonction générique soit un C++ intuitif, car les modèles C++ fonctionnent différemment des génériques.Le moyen C++ consiste à utiliser des objets de fonction - tout ce que vous pouvez mettre après () et cela a du sens pour le compilateur. Cela peut être un pointeur de fonction, une classe avec operator() et ainsi de suite. Cela fonctionne parce que les modèles C++ sont comme des macros de fantaisie, et aussi longtemps que le code a du sens avec les types substitués, vous êtes OK. Les génériques C# ne fonctionnent pas comme ça - ils sont plus restrictifs, probablement dans le but d'améliorer les messages d'erreur (puisque l'erreur d'obtenir des templates C++ est fameuse dans la sortie). Je ne sais pas trop sur les génériques C#, mais je pense qu'ils s'appuient sur quelque chose qui ressemble plus à des rappels, d'où l'utilité des génériques de la fonction.

Questions connexes