10
votes

Lire des arguments du modèle variadique

Je suis un peu confus sur la façon dont puis-je lire chaque argument de la tuple à l'aide de modèles variadiques.

Considérez cette fonction: P>

func(1,10,100,1000);


10 commentaires

Qu'as-tu manqué dans votre question précédente? ( Stackoverflow.com/Questtions/3634379/varididic-templates ) et pourquoi n'acceptez-vous pas les réponses à vos questions ?


Stackoverflow.com/Questions/3634379/varididic-Templates/...


La réponse doit être dans le fil lié (par MOTTI, pas de upvotes?)


@Svisitor: La réponse que je recherche n'est pas illustrée dans la suggestion de la Motti. J'ai demandé à propos du mécanisme de lire chaque paramètre séparément. Peut-être que je n'ai pas bien compris ses exemples !! Dans son exemple, il appelle la fonction max que jamais ne sera déclarée.


@Eonon: J'accepte les réponses. Il n'y a pas de fond ici pour désactiver les réponses ..


@ cerneon: Que dois-je faire pour accepter les réponses ???


@sami: Lisez la FAQ au moins une fois ... citant de celui-ci: Lorsque vous avez décidé quelle réponse vous est le plus utile, marquez-la comme réponse acceptée en cliquant sur le chèque Contour de la boîte à gauche de la réponse.


En fait, j'ai trouvé l'exemple posté dans la question précédente compréhensible? Que quelqu'un puisse me clarifier plus en détail comment puis-je lire les paramètres séparément.


@sami: Ce n'est pas le point. Vous avez posé 5 questions et n'a pas accepté de réponse pour aucun d'entre eux. Qu'est-ce qui n'allait pas avec celui-ci ( Stackoverflow.com / Questions / 3626483 / ... )? Si vous ne vous sentez pas comme si vous pouviez passer 10 secondes à remercier quelqu'un qui a pris une partie de son temps pour Aide Vous, peut-être que ce n'est pas le bon site pour vous.


@Eonon: Je ne savais pas que j'accepterai la réponse que j'ai trouvée utile. Je suis un débutant dans ce forum. Je remercie tout le monde qui passe une partie de son temps pour aider / conseiller à d'autres utilisateurs. Je sais maintenant comment ça marche. :)


4 Réponses :


16
votes

Vous devez fournir des substitutions aux fonctions de consommation du premier N code> (généralement un).

vector<int> reverse(int i) {
    vector<int> ret;
    ret.push_back(i);
    return ret;
}

template <class... R>
vector<int> reverse(int i, R... r) {
    vector<int> ret = reverse(r...);
    ret.push_back(i);
    return ret; 
}

int main() {
    auto v = reverse(1, 2, 3, 4);
    for_each(v.cbegin(), v.cend(), 
        [](int i ) { 
            std::cout << i << std::endl; 
        }
    );
}


15 commentaires

@MOTTI: J'ai compris ce que tu veux dire. Mais j'ai toujours deux questions: 1- Si je veux spécifier le type de données, puis-je appeler la fonction FOO de cette façon: Foo (42, vrai, "A", "Bonjour") 2- Où puis-je lire les valeurs pour la stocker où je veux stocker après le déballer et c'était ma principale question!


@sami, 1. Je ne suis pas sûr de ce que la standard dit, mais g ++ accepte foo (42) auquel cas je reçois * plutôt que 42 ce qui signifie qu'il a contraint l'argument à un char .


@sami, 2. Si celles-ci sont de types différents, vous ne pouvez pas les stocker dans un tableau régulier (sauf si vous utilisez Boost :: Tout ou quelque chose de similaire comme suggéré par Kirill)


Il semble que l'état de fin devrait venir en premier.


@MOTTI: THNAKS. Je ne sais pas pourquoi il y a plus de 100 exemples décrivent comment décompresser et sortir les arguments et en même temps, il n'existe aucun exemple qui décrit la manière dont chaque paramètre pourrait être stocké individuellement.


@sami, j'ai mis à jour ma question voir si elle répond aux choses pour vous.


@MOTTI: Merci, à propos de la tuple, vous avez arrêté où ma question commence (où sont stockées les paramètres et comment puis-je avoir accès à chacun). La deuxième suggestion semble jolie, mais je pense que le corps de la fonction principale contient une erreur. Puissiez-vous me clarifier comment cette ligne fonctionne de vecteur ret = inverse (r ...);


@sami, la deuxième solution compile et fonctionne comme prévu sur g ++ 4.5 Que pensez-vous que cela ne va pas avec cela? La manière dont vecteur int ret = inverse (r ...); fonctionne est-il crée un appel pseudo récursif qui se termine lorsque le pack d'arguments contient exactement un élément (la première fonction) qui renvoie un Vecteur avec un élément et chaque pile de la récursion ajoute un autre élément jusqu'à ce que vous ayez tout (dans l'ordre inverse)


@MOTTI: Lorsque je compile votre deuxième exemple, je reçois toujours une erreur de compilation. Puissiez-vous fournir l'exemple complet s'il vous plaît !!


@sami Vous devez inclure les en-têtes suivants tuple , vecteur , iostream et algorithme et ont en utilisant Espace de noms Std


@MOTTI: Merci. J'ai une question liée à votre exemple. Quel est l'avantage de passer le premier argument dans ce vecteur de ligne inverse (int i, r ... r)? Qu'en est-il si vous ne transmettez que le modèle variadique?


@MOTTI: J'ai inclus les préprovuseurs que vous avez mentionnés, mais j'ai toujours obtenu cette erreur: expression primaire attendue avant '[Erreur de jeton: expression primaire attendue avant'] 'Erreur de jeton: expression primaire attendue avant' int '


@sami, en ce qui concerne le premier argument, si vous envoyez l'ensemble du pack, vous n'êtes pas plus proche de la finition, c'est comme une récursion que vous souhaitez que chaque étape de réduire le problème (ici le nombre de params). Concernant l'erreur, c'est ceci dans le pour_acheche (nulle part ailleurs a [) Si tel est peut-être votre compilateur ne prend pas en charge les expressions Lambda, utilisez simplement un régulier pour boucle pour imprimer le contenu du vecteur .


@MOTTI: Merci beaucoup. Puissiez-vous fournir un exemple plus de détails pour le premier cas dans lequel les packs proviennent de types différents, comme vous l'avez fait dans le second cas. Je manque toujours le mécanisme pour accéder aux paramètres du pack s'ils forment des types différents.


@sami, s'il vous plaît lisez sur tuple s la manière d'y accéder est get (tuple) n est la constante de la compilation de l'index.



1
votes

Si vous devez stocker des arguments dans le tableau, vous pouvez utiliser un tableau de Boost :: n'importe quel code> comme suit:

template<typename... A> int func(const A&... args)
{
  boost::any arr[sizeof...(A)] = { args... };
  return 0;
}


0 commentaires

3
votes

Si les arguments sont tous du même type, vous pouvez stocker les arguments dans un tableau comme celui-ci (à l'aide du type de premier argument pour la matrice):

#include <vector>
#include <iostream>
#include <iterator>

template <class Iter>
std::reverse_iterator<Iter> make_reverse_iterator(Iter it)
{
    return std::reverse_iterator<Iter>(it);
}

template <class T>
std::vector<T> reverse(std::initializer_list<T> const & init)
{

    return std::vector<T>(make_reverse_iterator(init.end()), make_reverse_iterator(init.begin()));
}

int main() {
    auto v = reverse({1, 2, 3, 4});
    for (auto it = v.begin(); it != v.end(); ++it) {
        std::cout << *it << std::endl;
    }
} 


3 commentaires

La bibliothèque de boost prend-elle également en charge les conteneurs STL pour des modèles variadiques aussi?


Qu'en est-il que les arguments ne soient pas du même type de données?


Un "conteneur" standard pour les valeurs de différents types est un std :: tuple .



2
votes

Pour collecter dans un tableau si les arguments ont des types différents, vous pouvez également utiliser std :: common_type <> xxx

donc par exemple, FUNC (STD :: String ("Bonjour"), "Folks") Crée un tableau de std :: String .


0 commentaires