1

単項ファンクターを boost::phoenix ラムダ式に置き換えたい Visual Studio 2008 C++ アプリケーションがあります。

私の場合、文字列を含むオブジェクトのリストがあります。指定した文字列と一致しない文字列を持つすべてのオブジェクトを削除したい。したがって、次のようなアルゴリズムを使用します。

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しかし、コードを少しクリーンアップして、ファンクタを取り除き、次のような単純なラムダ式に置き換えたいと思います。

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

Fooboost:phoenix:actor をオブジェクトのように見せるにはどうすればよいですか?

4

2 に答える 2

4

Phoenix から直接使用std::string::compare()するのは、過負荷であり、そのアドレスを取得する必要があるため、かなり醜いです。

phx::bind(
    static_cast<int (std::string::*)(std::string const&) const>(
        &std::string::compare
    ),
    phx::cref(some_type),
    phx::bind(&Foo::my_type, arg1)
) != 0

ただし、Luc のヒントに従って単純にオブジェクトの等価性を比較すると、より扱いやすくなります。

phx::cref(some_type) != phx::bind(&Foo::my_type, arg1)
于 2011-08-29T22:02:43.970 に答える