Использование boost :: format в boost :: lambda - PullRequest
5 голосов
/ 08 декабря 2010

По некоторым причинам я не могу использовать 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::vectorstd::for_each на самом деле boost::fusion::for_each).

Ответы [ 2 ]

4 голосов
/ 08 декабря 2010

По какой-то причине ваш код оценивает boost::format("%10d") % bl::_1 сразу, а не при каждом вызове лямбды.

Чтобы предотвратить это, вам нужно обернуть 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));
2 голосов
/ 08 декабря 2010

Держу пари, что вы столкнулись с тем фактом, что используемый формат больше не используется.

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

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

Другими словами, использование% в формате фактически заменяет строковые данные тем, что вы%углубился в это.Круче то, что второе использование выше молча не удастся.

Я знаю, что-то нелогичное, но это то, что есть.

...