5

由于某种原因,我无法boost::formatboost::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)。

4

2 回答 2

4

For some reason, your code evaluates boost::format("%10d") % bl::_1 immediately, rather than on each invocation of the lambda.

To prevent this, you need to wrap boost::format("%10d") in a call to bl::var, just as you have done with std::cout.

Unfortunately, doing this requires Boost.Lambda to deduce the return type of the call to operator%, which it is unable to do. Therefore the return type must be specified explicitly, using bl::ret. Note that this return type must be a reference, in order that std::cout accesses the returned object directly rather than a copy of it.

We thus get the following code, which produces the expected output:

std::for_each(v.begin(), v.end(), bl::var(std::cout) <<
    bl::ret<const boost::format &>(bl::var(boost::format("%10d")) % bl::_1));
于 2010-12-07T23:44:25.610 回答
2

我敢打赌,您会遇到这样一个事实,即使用的格式不再可用。

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

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

In other words, using % on a format actually replaces the string data with whatever you %'d into it. The cooler thing is that the second use above will silently fail.

I know, kind of counter-intuitive, but it is what it is.

于 2010-12-07T22:04:10.843 回答