Использование Boost :: Format в Boost :: rambda
-
09-10-2019 - |
Вопрос
По какой -то причине я не могу использовать boost::format
в boost::lambda
. Анкет Вот (надеюсь) компилируемое упрощение моего кода:
#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);
}
- Первое
std::for_each
производит ожидаемый выход - Второй
std::for_each
только выводит пробелы без какого -либо числа
Это почему ? Я действительно не знаком с boost::lambda
Так что я мог бы упустить очевидное здесь.
Пожалуйста, не предлагайте std::copy
Ответы на основе: мой фактический код не работает на std::vector
но на boost::fusion::vector
(и std::for_each
на самом деле boost::fusion::for_each
).
Решение
По какой -то причине ваш код оценивает boost::format("%10d") % bl::_1
немедленно, а не на каждом вызове Lambda.
Чтобы предотвратить это, вам нужно обернуть boost::format("%10d")
призыв к bl::var
, так же, как вы сделали с std::cout
.
К сожалению, это требует Boost.lambda, чтобы вывести тип возврата вызова operator%
, что это не может сделать. Поэтому тип возврата должен быть указан явно, используя bl::ret
. Анкет Обратите внимание, что этот тип возврата должен быть ссылкой, чтобы, чтобы std::cout
Доступа к возвращенному объекту напрямую, а не его копию.
Таким образом, мы получаем следующий код, который дает ожидаемый выход:
std::for_each(v.begin(), v.end(), bl::var(std::cout) <<
bl::ret<const boost::format &>(bl::var(boost::format("%10d")) % bl::_1));
Другие советы
Я держу пари, что вы сталкиваетесь с тем фактом, что используемый формат больше не используется.
boost::format f("...");
std::string s = f % ... ;
std::string s2 = f % other options...; // FAIL! f has been changed by the above use!
Другими словами, использование % в формате фактически заменяет строковые данные на все, что вы % 'D в него. Прохладнее, что второе использование выше будет молча неудача.
Я знаю, что-то вроде нелогично, но это то, что есть.