在 boost::lambda 中使用 boost::format

发布于 2024-10-07 04:08:29 字数 1015 浏览 7 评论 0原文

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

For some reason, I fail to use boost::format in a boost::lambda. Here is a (hopefully) compilable simplification of my code :

#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);
}
  • The first std::for_each produces the expected output
  • The second std::for_each only outputs whitespaces without any number

Why is that ? I'm really not familiar with boost::lambda so I might be missing the obvious here.

Please do not suggest std::copy based answers : my actual code does not work on std::vector but on boost::fusion::vector (and std::for_each is in fact a boost::fusion::for_each).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅忆流年 2024-10-14 04:08:29

由于某种原因,您的代码会立即计算 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));

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));
拥有 2024-10-14 04:08:29

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

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

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

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

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

My bet is that you're running into the fact that a format used is no longer usable.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文