Question

Pour une raison quelconque, je n'utiliser boost::format dans un boost::lambda. Voici un (je l'espère) la simplification compilable de mon code:

#include <algorithm>
#include <iomanip>
#include <iostream>

#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/lambda/lambda.hpp>

namespace bl = boost::lambda;

int main()
{
    const std::vector<int> v = boost::assign::list_of(1)(2)(3);
    std::for_each(v.begin(), v.end(), bl::var(std::cout) << std::setw(10) << bl::_1);
    std::for_each(v.begin(), v.end(), bl::var(std::cout) << boost::format("%10d") % bl::_1);
}
  • La première std::for_each produit la sortie attendue
  • La deuxième std::for_each ne sort que sans numéro espacements

Pourquoi? Je ne suis vraiment pas familier avec boost::lambda donc je pourrais être absent de l'évidence ici.

S'il vous plaît ne suggère pas des réponses basées sur std::copy. Mon code actuel ne fonctionne pas sur std::vector mais boost::fusion::vector (et std::for_each est en fait un boost::fusion::for_each)

Était-ce utile?

La solution

Pour une raison quelconque, votre evalue de code boost::format("%10d") % bl::_1 immédiatement, plutôt que sur chaque appel du lambda.

Pour éviter cela, vous devez envelopper boost::format("%10d") dans un appel à bl::var, comme vous l'avez fait avec std::cout.

Malheureusement, cette opération nécessite Boost.Lambda de déduire le type de retour de l'appel à operator%, qu'il est incapable de le faire. Par conséquent, le type de retour doit être spécifié explicitement, en utilisant bl::ret. Notez que ce type de retour doit être une référence, afin que std::cout accède à l'objet retourné directement au lieu d'une copie de celui-ci.

On obtient ainsi le code suivant, qui produit le résultat attendu:

std::for_each(v.begin(), v.end(), bl::var(std::cout) <<
    bl::ret<const boost::format &>(bl::var(boost::format("%10d")) % bl::_1));

Autres conseils

Mon pari est que vous êtes en cours d'exécution dans le fait qu'un format utilisé n'est plus utilisable.

boost::format f("...");

std::string s = f % ... ;
std::string s2 = f % other options...; // FAIL!  f has been changed by the above use!

En d'autres termes, en utilisant% sur un format remplace en fait les données de chaîne avec tout ce que vous% 'd en elle. La chose est plus froide que la deuxième utilisation ci-dessus en silence échec.

Je sais, sorte de contre-intuitif, mais il est ce qu'il est.

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