2

vector挿入したい がありsetます。これは 3 つの異なる呼び出しのうちの 1 つです (他の 2 つは を含むより複雑ですboost::lambda::if_())、この単純なケースを解決することは、他の問題を解決するのに役立ちます。

std::vector<std::string> s_vector;
std::set<std::string> s_set;
std::for_each(s_vector.begin(), s_vector.end(), s_set.insert(boost::lambda::_1));

残念ながら、これは変換エラー メッセージ (に変換しようとしています) で失敗しboost::lambda::placeholder1_typeますstd::string

それで...これの何が問題なのですか?

4

5 に答える 5

3

エラーは本当に厄介ですが、3つのオーバーロードがあるため、どのset::insertを使用するかがわからないという事実に要約されます。

使用したい関数へのポインターを指定することにより、bindに役立つ手を与えることにより、あいまいさを回避できます。

typedef std::set<std::string> s_type;
typedef std::pair<s_type::iterator, bool>(s_type::*insert_fp)(const s_type::value_type&);
std::for_each(s_vector.begin(), s_vector.end(), boost::bind(static_cast<insert_fp>(&s_type::insert), &s_set, _1));

きれいではありませんが、うまくいくはずです。

于 2008-11-11T00:39:31.250 に答える
2

forループを使用します:-D

于 2008-11-11T01:00:24.623 に答える
2

ベクトルをセットにコピーするだけで、std::copy と挿入イテレータを使用できます。何かのようなもの:

std::copy(s_vector.begin(), s_vector.end(), std::inserter(s_set, s_set.end()));

もちろん、これは boost::lambda をまったく使用していないため、これを一般化してやりたいことを実行するのにはおそらく役立ちません。ここで何をしようとしているのかをもっと知っておくとよいでしょう。lambda::_if についてのあなたの言及に基づいて、セットに挿入する前に、ラムダが入力ベクトルの何らかのフィルタリングを行うと仮定します。

次の (完全でテスト済みの) 例は、ベクターから 4 文字以下の文字列のみをセットにコピーする方法を示しています。

#include <boost/assign/list_of.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/test/minimal.hpp>

#include <set>
#include <vector>
#include <algorithm>

using namespace std;
using namespace boost::lambda;
using namespace boost::assign;

int test_main(int argc, char* argv[])
{
    vector<string> s_vector = list_of("red")("orange")("yellow")("blue")("indigo")("violet");
    set<string> s_set;

    // Copy only strings length<=4 into set:

    std::remove_copy_if(s_vector.begin(), s_vector.end(), std::inserter(s_set, s_set.end()),
                        bind(&string::length, _1) > 4u);

    BOOST_CHECK(s_set.size() == 2);
    BOOST_CHECK(s_set.count("red"));
    BOOST_CHECK(s_set.count("blue"));

    return 0;
}

うまくいけば、これで何かを続けることができますか?

また、boost::bind と boost::lambda::bind は 2 つの異なる獣であるという上記のポイントを繰り返します。概念的には似ていますが、異なるタイプの出力を生成します。後者のみが他のラムダ演算子と組み合わせることができます。

于 2008-11-11T02:38:57.467 に答える
1

問題の一部はfor_each()、ファンクターを期待していて、関数呼び出しの結果を渡していることだと思います。したがって、コードはvector<string>::insert()最初に を呼び出してから、その呼び出しの結果を に渡しfor_each()ます。正確な構文はわかりませんが、ここではバインドをラムダと組み合わせて使用​​したいと思います。例えば

for_each(s_vector.begin(), s_vector.end(),
         boost::bind(set<string>::insert, s_set, boost::lambda::_1));
于 2008-11-11T00:20:09.480 に答える
0

残念ながら、これは:

std::for_each(s_vector.begin(), s_vector.end(),
        lambda::bind(&std::set<std::string>::insert, s_set, lambda::_1));

動作しません。(s_setが何であるかという理由で、set :: insertを使用したことに注意してください。)エラーは本当に厄介ですが、3つのオーバーロードがあるため、どのset::insertを使用するかがわからないという事実に要約されます。私が使用しようとしているのは、pair :: iterator、bool>(値の挿入)を返すセットです。明らかに、それは機能していません。

boost :: lambda::bindではなくboost::bindを使用していることに気づきました-それは意図的なものでしたか?(動作が少し異なるように見えます。)

関数呼び出しの結果ではなく、ファンクターを期待するのは正しいと思います。これはファンクターに変えられると確信していますが、私の脳は今答えを見ていません。

ありがとう。

于 2008-11-11T00:34:17.047 に答える