【问题标题】:Using boost::format in a boost::lambda在 boost::lambda 中使用 boost::format
【发布时间】:2010-12-07 21:53:31
【问题描述】:

由于某种原因,我未能在 boost::lambda 中使用 boost::format。这是我的代码的(希望)可编译的简化:

#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)。

【问题讨论】:

    标签: c++ boost-lambda boost-format


    【解决方案1】:

    由于某种原因,您的代码会立即评估 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::lambda::var 只有在两个参数都不是 lambda 表达式时才需要。我的目标是使用boost::lambda 获得一个简洁明了的语法:( 太糟糕了
    【解决方案2】:

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

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

    换句话说,在格式上使用 % 实际上会将字符串数据替换为您输入的任何内容。更酷的是,上面的第二次使用会静默失败。

    我知道,有点违反直觉,但事实就是如此。

    【讨论】:

    • 感谢您的回答,但我相信您提供的代码可以按预期工作。引用 boost.format 文档“一旦提供了所有参数,您就可以将格式对象转储到流中。[...] 结果字符串在格式对象中保持可访问性,直到传递另一个参数,此时它被重新初始化。 "第二个% 确实重新初始化了格式,但这对我来说应该是件好事!
    • 根据我的经验,它不会,但如果你的米数不同,我建议忽略我的回复。不知道你还有什么问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多