0

私はブーストの新しい初心者です。そして、これが私のテストコードです。

  using namespace boost::lambda;
  std::vector<std::string> strings; 
  strings.push_back("Boost"); 
  strings.push_back("C++"); 
  strings.push_back("Libraries"); 

  std::vector<int> sizes; 

  std::for_each(
   strings.begin(),
   strings.end(),
   bind(
  &std::vector<int>::push_back,
  sizes,
  bind<std::size_t>(&std::string::size, _1)));

  std::for_each(sizes.begin(), sizes.end(), var(std::cout)<<_1);

プロジェクトをビルドしてエラーを生成します。

エラーC2665:'boost :: lambda :: function_adaptor :: apply':2つのオーバーロードのいずれもすべての引数タイプを変換できませんでした

何が悪いのかしら?本当に感謝しています。

4

3 に答える 3

1

最初の問題はstd::vector::push_back、C++0x の関数がオーバーロードされていることです (左辺値参照パラメーターを持つオーバーロードと、右辺値参照パラメーターを持つオーバーロードがあります)。

2 番目の問題は、標準ライブラリのメンバー関数の型が指定されていないことです。実装者は、既定の引数を使用して追加のパラメーターをメンバー関数に追加することが許可されており、メンバー関数の追加のオーバーロードを追加することが許可されています。ポータブル。曖昧さ回避の例では、この 2 番目の問題を無視することを前提としています。

メンバー関数へのポインターを正しい型にキャストする必要があります。そうしないと、C++0x ライブラリの実装では機能しません (メンバー関数へのポインターがあいまいになります)。あなたは必要になるでしょう:

(void (std::vector<int>::*)(const int&))&std::vector<int>::push_back

C++0x 関数ライブラリを使用すると、次のように動作します ( に置き換えるstd::boost::、Boost でも動作するはずです。テストできません)。

std::for_each(
    strings.begin(),
    strings.end(),
    std::bind(
       (void (std::vector<int>::*)(const int&))&std::vector<int>::push_back,
       std::ref(sizes),
       std::bind(&std::string::size, std::placeholders::_1)));

これは本当に混乱していることに注意してください。 for ループを使用するだけでより明確になります。

for(std::vector<int>::const_iterator i(strings.begin()); i != strings.end(); ++i)
{
    sizes.push_back(i->size());
}

または、ラムダ式をサポートするコンパイラがある場合:

std::for_each(strings.begin(), strings.end(), 
              [&](const std::string& s) { sizes.push_back(s.size()); });

または、もっと楽しむために:

std::transform(strings.begin(), strings.end(), std::back_inserter(sizes),
               [](const std::string& s) { return s.size(); });
于 2010-10-29T03:20:11.103 に答える
0
  namespace lambda = boost::lambda;
  std::vector<std::string> strings; 
  strings.push_back("Boost"); 
  strings.push_back("C++"); 
  strings.push_back("Libraries"); 

  std::vector<int> sizes; 

  std::for_each(
   strings.begin(),
   strings.end(),
   bind(
  &std::vector<int>::push_back,
  sizes,
  bind<std::size_t>(&std::string::size, _1)));

  std::for_each(sizes.begin(), sizes.end(), lambda::var(std::cout)<< lambda::_1);
于 2010-10-29T03:18:02.387 に答える
0

または、独自の関数オブジェクトを作成できます。

template <typename T>
struct c_inserter
{
    T& c;

    c_inserter(T& c) : c(c) {}
    void operator()(string& v) { c.push_back(v.size()); }
};

ostream_iterator次に、それを使用します( と 別のをcopy置き換えることに注意してくださいlambda):

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

#include <boost/lambda/lambda.hpp>

int main() 
{
    std::vector<std::string> strings;
    strings.push_back("Boost");
    strings.push_back("C++");
    strings.push_back("Libraries");

    std::vector<int> sizes;

    std::for_each(
            strings.begin(),
            strings.end(),
            c_inserter< vector<int> >(sizes));

    copy(sizes.begin(), sizes.end(), ostream_iterator<int>(cout,":"));
    cout << endl;
}
于 2010-10-29T04:01:22.280 に答える