Mit boost :: Format in einem boost :: Lambda
-
09-10-2019 - |
Frage
Aus irgendeinem Grund scheitern ich boost::format
in einem boost::lambda
zu verwenden. Hier ist eine (hoffentlich) übersetzbar Vereinfachung meines Codes:
#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);
}
- Die erste
std::for_each
erzeugt die erwartete Ausgabe - Die zweite
std::for_each
gibt nur Leerzeichen ohne Zahl
Warum ist das so? Ich bin wirklich nicht vertraut mit boost::lambda
so ich könnte hier die offensichtlich fehlt.
Bitte schlagen nicht std::copy
fundierte Antworten. Meine eigentliche Code nicht funktioniert auf std::vector
aber auf boost::fusion::vector
(und std::for_each
in der Tat ein boost::fusion::for_each
)
Lösung
Aus irgendeinem Grund, den Code auswertet boost::format("%10d") % bl::_1
sofort, anstatt bei jedem Aufruf des Lambda.
Um dies zu verhindern, müssen Sie boost::format("%10d")
in einem Aufruf von bl::var
wickeln, so wie Sie mit std::cout
getan haben.
Leider ist dies zu tun erfordert Boost.Lambda den Rückgabetyp des Anrufs operator%
abzuleiten, die es nicht in der Lage ist zu tun. Daher ist der Rückgabetyp muss explizit angegeben werden, bl::ret
verwenden. Beachten Sie, dass diese Rückgabetyp eine Referenz, um sein muss, dass std::cout
das zurückgegebene Objekt direkt, anstatt eine Kopie davon zugreift.
Wir erhalten somit den folgenden Code, der die erwartete Ausgabe erzeugt:
std::for_each(v.begin(), v.end(), bl::var(std::cout) <<
bl::ret<const boost::format &>(bl::var(boost::format("%10d")) % bl::_1));
Andere Tipps
Meine Wette ist, dass Sie in die Tat ausführen, dass ein Format verwendet wird, ist nicht mehr verwendbar.
boost::format f("...");
std::string s = f % ... ;
std::string s2 = f % other options...; // FAIL! f has been changed by the above use!
Mit anderen Worten, mit% auf ein Format ersetzt tatsächlich die String-Daten mit dem, was Sie% 'd hinein. Der Kühler ist, dass der zweite Einsatz über Willen leise versagen.
ich weiß, Art des kontra-intuitiver, aber es ist, was es ist.