Question

Boost lambda permet de remplacer le type de retour en utilisant le modèle de déduite ret<T>. J'ai essayé la recherche d'équivalent à Phoenix mais n'a pas pu en trouver un.

Y at-il un équivalent à Phoenix? Je sais comment faire mon remplacement, mais je préfère ne pas. merci

Était-ce utile?

La solution

Réécrire. Je Maladroit sur ma première réponse (il était tard), je vais essayer à nouveau

Permettez-moi de donner quelques exposition pour des gens comme moi qui pourrait manquer votre point la première fois. En boost :: lambda, lors de l'utilisation des types définis par l'utilisateur dans les expressions de l'opérateur, on doit utiliser la fonction RET <> à déduction de type de priorité de retour. En effet, le système de déduction de type retour lambda ne supporte que natif (et stl? Je ne me souviens pas) types directement. Un court exemple:

using namespace boost::lambda;

struct add_t{
    add_t(int i) : i(i) {};
    add_t operator+(const add_t& other) const{
        return add_t(i + other.i);
    }
    int i;
};

(_1 + _2)(add_t(38), add_t(4));           // RETURN TYPE DEDUCTION FAILS
ret<add_t>(_1 + _2)(add_t(38), add_t(4)); // OK

phénix cependant, aucune indication ne sont nécessaires (notez que littéraux et non-const temporaires ne peuvent pas apparaître dans une liste d'arguments de Phoenix):

using namespace boost::phoenix;

add_t i(38), j(4);
(_1 + _2)(i, j);    // JUST FINE

Le système de déduction de type de retour est complètement différent et beaucoup plus naturel à Phoenix; il en déduire correctement le type de retour des opérateurs qui utilisent la sémantique conventionnelle. Plus précisément, le type de retour doit correspondre au type de l'un des opérandes, une référence, pointeur ou pointeur const à l'un des types d'arguments, ou être un itérateur conteneur stl / conteneur d'un de ces types. Il y a une écriture agréable d'déduction type de retour de Phoenix dans type_deduction.hpp tête pour plus de détails.

Alors maintenant, je lis votre question, comment la sémantique des opérateurs non conventionnelles traitées à Phoenix?

Considérons la paire étrange suivant des types comme un exemple

struct add_ret_t{
    add_ret_t(int i) : i(i) {};
    int i;
};

struct add_t{
    add_t(int i) : i(i) {};
    add_ret_t operator+(const add_t& other) const{
        return add_ret_t(i + other.i);
    }
    int i;
};

Pour lambda, c'est pas de problème, il suffit d'utiliser la fonction de RET:

using namespace boost::lambda;

ret<add_ret_t>(_1 + _2)(add_t(38), add_t(4)); // OK

Mais Phoenix ne peut pas traiter avec cet opérateur (pouvez-vous blâmer?) Parce que le type de retour est pas lié aux arguments, et il n'y a aucun moyen d'indiquer directement le type de retour à Phoenix. S'il y a une bonne raison d'utiliser un opérateur comme celui-ci, un cas pourrait être ajouté au système de déduction de type, mais je ne peux pas voir une façon de le faire sans le piratage type_deduction.hpp ou de branchement d'une bonne partie de phénix.

Sinon, je me suis un petit hack pour remplacer les types de retour pour les opérateurs spécifiques. Le result_of_ opération structures de modèle dans boost / esprit / home / Phoenix / opérateur / arithmetic.hpp (lignes 39-56 liste les types struct, boost 1,43) exécuter la déduction de type quand ils sont instanciés et stocker les résultat. Donc, tout ce qui est nécessaire est de fournir des spécialisations de modèle pour les opérations de problèmes, qui ne contiennent un besoin typedef spécifiant le type de retour. Exemple ( CodePad plein src):

using namespace boost::phoenix;

namespace boost{ namespace phoenix{

//override add_t addition to give add_ret_t
template <> struct result_of_plus<add_t&, add_t&> { typedef add_ret_t type; };

//override int addition to give char
template <> struct result_of_plus<int&, int&> { typedef char type; };

}}

int main()
{
    add_t i = 1, j = 7;
    std::cout << ((_1 + _2)(i, j)).i << std::endl;

    int k = 51, l = 37;
    std::cout << ((_1 + _2)(k, l)) << std::endl;

    return 0;
}

Ceci est certainement pas un remplacement de ret, mais dans un certain sens, son meilleur depuis son mondial. S'il y a beaucoup d'opérateurs à la surcharge, l'ensemble des opérations pourrait être macroed.

Autres conseils

AFAIK, ce (ou quelque chose de similaire) est pas pris en charge à Phoenix. Si vous avez décrit votre cas d'utilisation, je pourrais être en mesure d'aider, cependant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top