4

boost::phoenixC++11 をサポートしていない古いコンパイラで C++ ラムダ式をエミュレートしようとしていますが、ラムダ式内から単純な関数を呼び出すことができません。

C++11 バージョン:

[](unsigned a) { foo( a ); }( 12678u );   // calls foo( 12678u )

私の Phoenix Lambda コードは次のとおりです。

#include <cstdint>
#include <iostream>
#include <boost/phoenix.hpp>

namespace ph = boost::phoenix;
using ph::local_names::_a;
using ph::placeholders::arg1;

void foo( uint32_t val )
{
   std::cout << "\t" << __func__ << "( " << val << " ) called...\n";
}

int main()
{
   auto myLambda = ph::lambda( _a = arg1 )
      [
          foo( _a )
          //std::cout << ph::val( "Called with: " ) << _a << ph::val( "\n" )
      ]( 567u );

   myLambda();

    return 0;
}

これにより、次のコンパイラ エラーが発生します。

lambda-ex.cpp: In function ‘int main()’:
lambda-ex.cpp:18:19: error: cannot convert ‘const _a_type {aka const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::phoenix::detail::local<boost::phoenix::local_names::_a_key> >, 0l> >}’ to ‘uint32_t {aka unsigned int}’ for argument ‘1’ to ‘void foo(uint32_t)’ lambda-ex.cpp:20:15: error: unable to deduce ‘auto’ from ‘&lt;expression error>’

Phoenix ラムダ式内から関数を呼び出すにはどうすればよいですか?

phoneix::lambdas過去に C++11 ラムダを使用したのと同じ方法で使用できることを望んでいます。

auto lambda1 = [&]( uint32_t arg )
              {
                  func1( "Some Stuff", arg );
                  func2( "Some More Stuff", aValueFromLocalScope, arg );
                  func3( "Some Stuff", anotherValueFromLocalScope, arg );
              };

someFuncImpl( aParam, lambda1 );
4

2 に答える 2

6

ph::lambdaは、このジョブには不適切ph::lambdaなツールです ( は、フェニックス式内にネストされたラムダ式を作成するためのツールです)。フェニックス式はすでに関数であるため、フェニックス式を使用して関数を呼び出す方法 (バインド) を見つけ、複数の操作を順番に実行する方法 (演算子,) を見つけ、ローカル変数を導入する方法を見つけます (させて)。これをすべてまとめると、次のようになります。

#include <cstdint>
#include <iostream>
#include <boost/phoenix.hpp>

namespace ph = boost::phoenix;
using ph::local_names::_a;
using ph::placeholders::arg1;

#define FOO(name) void name( uint32_t val ) {\
    std::cout << "\t" << __func__ << "( " << val << " ) called...\n";\
}
FOO(foo)
FOO(bar)
FOO(baz)

int main()
{
    auto&& myLambda = ph::let(_a = arg1)
      [
          ph::bind(foo, _a),
          ph::bind(bar, _a),
          ph::bind(baz, _a)
      ];

    myLambda(342);

    return 0;
}
于 2013-04-06T14:17:13.827 に答える
4

あなたの例が些細なものであるかどうかは問題ではありません。Phoenix 以外の関数を呼び出すには、 を使用する必要がありphoenix::bindます。限目。

フェニックス スタイルのラムダは、単純な演算子のオーバーロード ベースの式に最も効果的に使用されます。任意の関数を呼び出すと見苦しくなります。

C++11 はラムダを言語機能として追加しませんでした。彼らがそうしたのは、さまざまなライブラリ ソリューションがすべて何らかの点で不十分だったからです。Phoenix の欠点の 1 つを発見しました。

于 2013-04-06T13:57:19.093 に答える