3

私が持っているとしましょう

struct Value { int foo(); };
size_t *begin = ...,
       *end   = ...;

ValueC ++ 03で多数のインデックスを並べ替える場合は、次のような面倒な記述を行う必要があります。

struct Comparator
{
    Value *data;
    Comparator(Value *data) : data(data) { }
    bool operator()(size_t a, size_t b)
    { return data[a].foo() < data[b].foo(); }
};
sort(begin, end, Comparator(data));

Boostを使って(おそらくBoost.Lambdaを使って)これをもっときれいに、できれば1行で書く方法はありますか?

4

2 に答える 2

6

いいえ。

Boost.Lambdaは、オーバーロードされた演算子を処理するときに最適に機能します。名前付き関数呼び出しを使用すると、Boost.Lambdaは、コードをより簡潔で読みやすくするのに非常に役立ちなくなります。関数バインダーなどを使い始める必要があります。

また、(インデックス付けされている値ではなく)ラムダパラメーターをインデックスとして使用しているという事実は、Boost.Lambdaライブラリでもoperator[]を使用している限りはおそらく問題になります。

これと同等のBoost.Lambdaを作成できます。しかし、それは私が「ニート」と呼ぶものではなく、「1行」は非常に長くなります。

Boost.Lambdaを標準ライブラリに組み込むだけでなく、C++11がラムダを言語に導入したのには理由があります。

ああ、忘れないでください:Boost.Lambdaは一般的に時代遅れと見なされています。代わりにBoost.Phoenixを使用してください。確かに、それはラムダがする以上にあなたを助けるつもりはありません。

于 2012-07-21T05:41:56.360 に答える
3

Boost.Phoenix(Boostの推奨ラムダライブラリ)の使用:

#include <boost/phoenix/phoenix.hpp>

{
    // for bind and ref
    using namespace boost::phoenix;

    using namespace boost::phoenix::placeholders;
    std::sort(begin, end
              , bind(&Value::foo, ref(data)[arg1]) < bind(&Value::foo, ref(data)[arg2]) );
}

別の方法は、LocalFunctionを使用することです。これにより、基本的に、実行していること(std::sortC ++ 03では許可されていないローカルタイプをに渡す)を移植可能な方法で実行できます。使用法は次のようになります(ただし、このコードのコードはテストされていません)。

#include <boost/local_function.hpp>

{
    int BOOST_LOCAL_FUNCTION(const bind& data, std::size_t lhs, std::size_t rhs)
    {
        return data[lhs].foo() < data[rhs].foo();
    } BOOST_LOCAL_FUNCTION_NAME(comparator)

    std::sort(begin, end, comparator);
}
于 2012-07-21T05:51:25.597 に答える