用 boost::phoenix actor 替换一元函子
我有一个 Visual Studio 2008 C++ 应用程序,我想用 boost::phoenix lambda 表达式替换一元函子。
就我而言,我有包含字符串的对象列表。我想删除带有与指定字符串不匹配的字符串的所有对象。所以,我使用这样的算法:
struct Foo
{
std::string my_type;
};
struct NotMatchType
{
NotMatchType( const std::string& t ) : t_( t ) { };
bool operator()( const Foo& f ) const
{
return f.my_type.compare( t_ ) != 0;
};
std::string t_;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector< Foo > list_of_foo;
/*populate with objects*/
std::string some_type = "some type";
list_of_foo.erase(
std::remove_if( list_of_foo.begin(),
list_of_foo.end(),
NotMatchType( some_type ) ),
list_of_foo.end() );
return 0;
}
这很好用。但是,我想稍微清理一下我的代码,去掉 NotMatchType
函子,并将其替换为一个简单的 lambda 表达式,如下所示:
using boost::phoenix::arg_names::arg1;
list_of_foo.erase(
std::remove_if( list_of_foo.begin(),
list_of_foo.end(),
arg1.my_type.compare( some_type ) != 0 ),
list_of_foo.end() );
显然,这是行不通的。
我也尝试过: ( arg1->*&Foo::my_type ).compare( some_type ) != 0
我需要做什么才能使 boost:phoenix:actor 看起来像Foo
对象?
I have a Visual Studio 2008 C++ application where I would like to replace a unary functor with a boost::phoenix lambda expression.
In my case, I have list of objects with containing a string. I want to remove all objects with a string that does not match the specified one. So, I use an algorithm like this:
struct Foo
{
std::string my_type;
};
struct NotMatchType
{
NotMatchType( const std::string& t ) : t_( t ) { };
bool operator()( const Foo& f ) const
{
return f.my_type.compare( t_ ) != 0;
};
std::string t_;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector< Foo > list_of_foo;
/*populate with objects*/
std::string some_type = "some type";
list_of_foo.erase(
std::remove_if( list_of_foo.begin(),
list_of_foo.end(),
NotMatchType( some_type ) ),
list_of_foo.end() );
return 0;
}
This works fine. But, I'd like to clean up my code a bit and get rid of the NotMatchType
functor and replace it with a simple lambda expression like this:
using boost::phoenix::arg_names::arg1;
list_of_foo.erase(
std::remove_if( list_of_foo.begin(),
list_of_foo.end(),
arg1.my_type.compare( some_type ) != 0 ),
list_of_foo.end() );
obviously, this doesn't work.
I have also tried: ( arg1->*&Foo::my_type ).compare( some_type ) != 0
What do I need to do to make the boost:phoenix:actor look like a Foo
object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
直接从 Phoenix 使用
std::string::compare()
非常难看,因为它重载了,我们需要获取它的地址:但是,如果我们遵循 Luc 的提示并简单地比较对象相等性,它就会变成更易于管理:
Using
std::string::compare()
directly from Phoenix is pretty ugly, since it's overloaded and we need to take its address:However, if we follow Luc's hint and simply compare object equality, it becomes more manageable:
给定两个字符串
lhs
和rhs
,则指定lhs == rhs
在语义上等同于lhs.compare(rhs) = = 0 。换句话说,你的仿函数所做的相当于
f.my_type != t_
。考虑到这一点,您可以将您想要的 Phoenix 表达为:
根据记录,您正在调用 Phoenix actor 上的成员
compare
。但由于该成员属于std::string
,因此这不是您想要的。我可以得到以下内容:最后一行是最终函子。但这并不好,因为没有可靠的方法来获取标准类型的重载成员的地址。换句话说,上面的第二行不能保证编译。
为了将来的参考,我在调用重载成员时更喜欢使用 lambda:
Given two strings
lhs
andrhs
, thenlhs == rhs
is specified to be semantically equivalent tolhs.compare(rhs) == 0
. In other words, what your functor is doing is equivalent to doingf.my_type != t_
.With that in mind, you can express what you want with Phoenix as:
For the record, you were calling a member
compare
on a Phoenix actor. Since that member belongs tostd::string
though, that's not what you want. I can get the following to work:where that last line is the final functor. But that's not good because there is no reliable way to get the address of an overloaded member of a Standard type. In other words the second line in the above is not guaranteed to compile.
For future reference I prefer lambdas when calling an overloaded member: