Comment obtenir le i-ème élément à partir d'un std::tuple quand je ne sais pas au moment de la compilation?
J'ai une variable i
de type std::size_t
et un tuple de type std::tuple
. Je veux obtenir le i
-ème élément du tuple. J'ai essayé ceci:
//bindings... is of type const T&...
auto bindings_tuple = std::make_tuple(bindings...);
auto binding = std::tuple_element<i, const T&...>(bindings_tuple);
Mais j'obtiens cette erreur de compilation en disant que le premier argument de modèle doit être une expression constante:
erreur: non-type de modèle argument de type '
std::size_t
' (aka 'unsigned long
') n'est pas une partie intégrante expression constante
Est-il possible d'obtenir le i
-ième élément d'un tuple, et comment le faire?
je voudrais le faire sans l'aide de boost, si possible.
Je pense que c'est une forte indication que vous avez besoin d'utiliser un vecteur, pas un n-uplet.
le problème avec les vecteurs (et tableaux), c'est que tous les éléments doivent être du même type.
Sauf si c'est un vecteur d'objets?
Vous avez besoin de connaître le type à la compilation. Vous connaissez l'index au moment de la compilation, ou avoir tous les éléments du même type. Il n'y a pas moyen de contourner cela.
Il ya quelque chose de mal quand la situation se présente. Un n-uplets de type doit être connu au moment de la compilation, comment pouvez-vous ne pas savoir de quel type d'accès au moment de la compilation? Vous ne serait même pas capable d'écrire ce que cette fonction est supposée retourner.
le problème avec les vecteurs (et tableaux), c'est que tous les éléments doivent être du même type.
Sauf si c'est un vecteur d'objets?
Vous avez besoin de connaître le type à la compilation. Vous connaissez l'index au moment de la compilation, ou avoir tous les éléments du même type. Il n'y a pas moyen de contourner cela.
Il ya quelque chose de mal quand la situation se présente. Un n-uplets de type doit être connu au moment de la compilation, comment pouvez-vous ne pas savoir de quel type d'accès au moment de la compilation? Vous ne serait même pas capable d'écrire ce que cette fonction est supposée retourner.
OriginalL'auteur | 2011-11-19
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas. Ce n'est pas un n-uplet est pour. Si vous avez besoin d'un accès dynamique à un élément, utilisez
std::array<T,N>
, qui est presque identique àstd::tuple<T,...,T>
mais vous donne la dynamique[i]
-opérateur; ou même une dynamique de conteneur commestd::vector<T>
.std::array<boost::any, N>
oustd::vector<boost::any>
.Éventuellement, si la question confond "modèle" et "type", il y a donc des limites à ce que l'on peut dire. En fin de compte, cela ne fait pas vraiment de sens non-compiler-temps de commutation entre types, du moins pas dans une mode élégante...
boost::variante permet, et j'imagine que vous auriez du faire quelque chose de similaire pour les n-uplets. Fondamentalement, vous avez une fonction qui prend un tuple, un index dans le n-uplet, et une classe de l'opérateur() surcharges pour chaque type. Approprié à une surcharge être appelée avec la valeur à l'index du n-uplet.
Comme je l'ai dit, "pas dans un élégant de la mode" 🙂 (je suis à moitié une blague. Si c'est vraiment le meilleur design pour votre problème, allez avec elle.)
OriginalL'auteur Kerrek SB
C'est possible:
Ce code affichera:
Échantillon de travail sur ideone: l'échantillon
Pourrait être polymorfic lambda
OriginalL'auteur Victor Laskin
Ce n'est probablement pas ce que l'OP veut, mais de toute façon, il est possible de retourner la je-ème élément à l'aide d'un run-time je si vous retournez un type variant comme
boost::variant
ouboost::any
,Par exemple:
sera d'impression:
(Le
boost::variant<T...>
nécessite g++ 4.7)OriginalL'auteur kennytm
La question ici, quel serait le type de type de retour si ce serait possible? Il doit être connu au moment de la compilation, mais tuple peut contenir des éléments de types différents.
Imaginons que nous avons un tuple de trois éléments:
Apparemment, l'obtention de la N-ième élément n'a pas beaucoup de sens. Ce type serait-il? On ne sait pas jusqu'à l'exécution. Cependant, plutôt que d'arriver à la N-ième élément, vous pouvez appliquer une fonction à elle, étant donné que tous les éléments à l'appui de certaines protocole commun:
Ce code "dynamique" des processus de l'élément, compte tenu de l'indice de
n
. Le protocole commun dans cet exemple est la fonctionfunc
qui peut faire quelque chose de significatif avec tous les types possibles utilisé dans le tuple.Cependant, la rédaction d'un tel code à la main est fastidieux, nous voulons le rendre plus générique. Commençons par l'extraction de la fonction de l'application, de sorte que nous pouvons réutiliser les mêmes
process
fonction pour différentes foncteurs:Dans ce cas
F
pourraient être mises en œuvre en tant que quelque chose comme:Faisons compilateur de générer tout le code, nous allons le rendre générique:
Utilisation:
Ce qui le rend complètement générique est une autre histoire, cependant. Au moins, il doit être indépendant de la tuple de type. Alors, vous voulez probablement generify type de retour de la functor, de sorte que vous pouvez revenir résultat significatif. Troisièmement, de faire foncteur d'accepter des paramètres supplémentaires.
P. S. je ne suis pas réel développeur C++, de sorte que l'approche ci-dessus peut être totale nonsence. Cependant, j'ai trouvé utile pour mon microcontrôleur projet où je veux, autant que possible, être réglé au moment de la compilation et pourtant suffisamment générique, donc je peux shuffle choses facilement. Par exemple, un "menu" dans mon projet est fondamentalement un tuple de "mesures", il y a chaque action est une catégorie distincte qui prend en charge protocole simple comme "imprimer votre étiquette à la position actuelle sur l'écran LCD" et "activer et exécuter votre INTERFACE utilisateur boucle".
OriginalL'auteur Ivan Dubrov