提高::功能及再次提高::拉姆达(boost::function & boost::lambda a

2019-10-29 14:49发布

后续岗位: 使用*宽和精度说明随着升压::格式

我试图使用boost::function创建一个使用lambda表达式来格式化一个字符串的函数boost::format 。 使用宽度和精度说明与格式字符串最后我想要实现的。 boost::format不支持使用的*宽度和精度说明,指示在文档 :

宽度或精度设置为星号(*)被用来通过printf的从一个参数读取这个域。 例如输出( “%1 $ D:%2 $ * 3 $。D:%4 $ * 3 $ d个\ n” 个,小时,分钟,精度,秒); 此类不支持这种机制现在。 所以这样的精确度或宽度字段由解析悄悄忽略。

所以我试图找到其他的方法来完成相同的目标。

这里是我到目前为止,这是不工作:

#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;
}

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

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 ==========

我的升压转换器的lambda表达式和功能的基本理解可能是缺乏的。 我怎样才能得到这个工作?

Answer 1:

我认为,对于这种情况,你可能需要使用boost.bind而不是boost.lambda。 问题的部分原因是升压:: IO ::组是一个函数模板采用并返回一个可变的对象,因此很难以创建功能<>声明适当的签名。 我想创建一个字符串格式化功能,用一个简单的签名,然后使用boost.bind创建从一个特定的格式函子。 即

#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;
}


Answer 2:

你应该再次检查Boost.Lambda的文件,看看它是能,什么不是。 例如,由于点运算符是不重载你不能像调用一个成员函数str()上那样的lambda表达式。 您需要使用bind了这一点:

bind(&format::str, … )

这实际上延伸到所有的非运营商的功能,据我可以告诉调用。 作为创建格式对象,你需要通过像这样推迟它的创建:

constructor<boost::format>(constant("%s"))  // untested

你看,与所有的额外噪音(绑定,构造函数,常数)你会得到一个相当复杂的,长的,而且很难破译lambda表达式。 最好的事情可能是完全避免它,只需使用一个简单的函数对象

struct myfunctor {
    string operator()(int a, string b) const {
        return …
    }
};
…
void foo() {
    …
    boost::function<string(int, string)> f = myfunctor();
    …
}


文章来源: boost::function & boost::lambda again
标签: c++ boost