首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >boost::function & boost::lambda

boost::function & boost::lambda
EN

Stack Overflow用户
提问于 2010-06-05 19:22:42
回答 2查看 3K关注 0票数 0

跟进帖子:具有boost::format的宽度和精确说明符

我试图使用boost::function创建一个函数,该函数使用lambda来用boost::format格式化字符串。最终,我想要实现的是使用宽度和精度的说明符来表示字符串的格式。boost::format不支持使用*宽度和精度说明符,如指示的在医生里

printf使用设置为星号(*)的宽度或精度从参数读取此字段。例如printf("%1$d:%2$.*3$d:%4$.*3$d\n",小时、最小、精度、秒);该类暂时不支持此机制。因此,这种精度或宽度字段在解析过程中会被忽略。

所以我试图找到其他方法来实现同样的目标。

以下是我到目前为止所拥有的,但没有起作用的地方:

代码语言:javascript
复制
#include <string>
#include <boost\function.hpp>
#include <boost\lambda\lambda.hpp>
#include <iostream>
#include <boost\format.hpp>
#include <iomanip>
#include <boost\bind.hpp>

int main()
{
 using namespace boost::lambda;
 using namespace std;

 boost::function<std::string(int, std::string)> f =
  (boost::format("%s") % boost::io::group(setw(_1*2), setprecision(_2*2), _3)).str();

 std::string s = (boost::format("%s") % f(15, "Hello")).str();

    return 0;
}

这会产生许多编译器错误:

代码语言:javascript
复制
1>------ Build started: Project: hacks, Configuration: Debug x64 ------
1>Compiling...
1>main.cpp
1>.\main.cpp(15) : error C2872: '_1' : ambiguous symbol
1>        could be 'D:\Program Files (x86)\boost\boost_1_42\boost/lambda/core.hpp(69) : boost::lambda::placeholder1_type &boost::lambda::`anonymous-namespace'::_1'
1>        or       'D:\Program Files (x86)\boost\boost_1_42\boost/bind/placeholders.hpp(43) : boost::arg<I> `anonymous-namespace'::_1'
1>        with
1>        [
1>            I=1
1>        ]
1>.\main.cpp(15) : error C2664: 'std::setw' : cannot convert parameter 1 from 'boost::lambda::placeholder1_type' to 'std::streamsize'
1>        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>.\main.cpp(15) : error C2872: '_2' : ambiguous symbol
1>        could be 'D:\Program Files (x86)\boost\boost_1_42\boost/lambda/core.hpp(70) : boost::lambda::placeholder2_type &boost::lambda::`anonymous-namespace'::_2'
1>        or       'D:\Program Files (x86)\boost\boost_1_42\boost/bind/placeholders.hpp(44) : boost::arg<I> `anonymous-namespace'::_2'
1>        with
1>        [
1>            I=2
1>        ]
1>.\main.cpp(15) : error C2664: 'std::setprecision' : cannot convert parameter 1 from 'boost::lambda::placeholder2_type' to 'std::streamsize'
1>        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>.\main.cpp(15) : error C2872: '_3' : ambiguous symbol
1>        could be 'D:\Program Files (x86)\boost\boost_1_42\boost/lambda/core.hpp(71) : boost::lambda::placeholder3_type &boost::lambda::`anonymous-namespace'::_3'
1>        or       'D:\Program Files (x86)\boost\boost_1_42\boost/bind/placeholders.hpp(45) : boost::arg<I> `anonymous-namespace'::_3'
1>        with
1>        [
1>            I=3
1>        ]
1>.\main.cpp(15) : error C2660: 'boost::io::group' : function does not take 3 arguments
1>.\main.cpp(15) : error C2228: left of '.str' must have class/struct/union
1>Build log was saved at "file://c:\Users\john\Documents\Visual Studio 2005\Projects\hacks\x64\Debug\BuildLog.htm"
1>hacks - 7 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我对boost的lambdas和功能的基本理解可能是缺乏的。我怎么才能让这个起作用?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-06-05 21:52:13

我认为,在这种情况下,您可能希望使用boost.bind而不是boost.lambda。部分问题是boost::io::group是一个函数模板,它接受并返回可变数量的对象,因此很难为function<>声明创建适当的签名。我将创建一个带有简单签名的字符串格式化函数,然后使用boost.bind创建一个特定的格式化函式。即

代码语言:javascript
复制
#include <string>
#include <iomanip>
#include <boost/function.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>

using namespace boost;
using namespace std;

string fmt_str(const string& s, int w, int p)
{
    return (format("%s") % io::group(setw(w), setprecision(p), s)).str();
}

int main()
{
    function<string (int, string)> f = bind(fmt_str, _2, _1, _1);
    string s = f(15, "Hello");
    return 0;
}
票数 2
EN

Stack Overflow用户

发布于 2010-06-06 07:29:31

您应该再次检查Boost.Lambda的文档,看看它能做什么和不能做什么。例如,由于点运算符不可重载,所以不能在这样的lambda表达式上调用像str()这样的成员函数。为此,您需要使用bind

代码语言:javascript
复制
bind(&format::str, … )

据我所知,这实际上扩展到所有非运算符函数调用。至于创建一个format对象,您需要通过这样的方式推迟创建它:

代码语言:javascript
复制
constructor<boost::format>(constant("%s"))  // untested

您可以看到,有了所有额外的噪声(绑定、构造函数、常量),您就得到了一个相当复杂、很长、很难解释lambda表达式的表达式。最好的办法可能是完全避免,只使用一个简单的函数对象。

代码语言:javascript
复制
struct myfunctor {
    string operator()(int a, string b) const {
        return …
    }
};
…
void foo() {
    …
    boost::function<string(int, string)> f = myfunctor();
    …
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2981724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档