この拡張は、キー一致 join_node を使用して入力タイプに関連付けられている関数からキーを取得します。join_node の各入力ポートの関数オブジェクトを提供する必要がなくなるため、既存のアプローチが単純化されます。
#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 #include "tbb/flow_graph.h"
この拡張は、key_matching<typename K, class KHash=tbb_hash_compare> ポリシーが使用されたときに join_node インターフェイスに特別なコンストラクターを追加します。コンストラクターは join_node( graph &g ) のようになります。この方法で構築された場合、join_node は、各着信メッセージについて key_from_message 関数を呼び出し、関連するキーを取得します。key_from_message のデフォルトの実装は次のとおりです。
namespace tbb { namespace flow { template <typename K, typename T> K key_from_message( const T &t ) { return t.key(); } } }ここで、T は、join_node の構築に使用される OutputTuple でユーザーが提供した型の 1 つ、K はノードのキー型です。デフォルトでは、メッセージクラスで定義された key() メソッドが呼び出されます。あるいは、メッセージの型と同じ名前空間に独自の key_from_message 関数を定義することもできます。この関数は C++ 引数依存ルックアップによって見つかり、デフォルトの実装の代わりに使用されます。
struct MyMessageType { int my_key; int my_value; // ADL が key_from_message 関数のカスタム実装を見つけるため // 次のメソッドは呼び出されません int key() const { // このメソッドは呼び出すべきではありません assert(false); return 0; } }; // key_from_message 関数のカスタム実装 template <typename K> int key_from_message(const MyMessageType &m) { return m.my_key; }
#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 #include "tbb/flow_graph.h" #include <cstdio> #include <cassert> class MyMessage { int my_key; float my_value; public: MyMessage( int k = 0, float v = 0 ) : my_key( k ), my_value( v ) {} int key() const { return my_key; } float value() const { return my_value; } }; int main() { using namespace tbb::flow; graph g; function_node<int, MyMessage> f1( g, unlimited, []( int i ) { return MyMessage( i, (float)i ); } ); function_node<int, MyMessage> f2( g, unlimited, []( int i ) { return MyMessage( i, (float)2 * i ); } ); function_node< tuple<MyMessage, MyMessage> > f3( g, unlimited, []( const tuple<MyMessage, MyMessage> &t ) { assert( get<0>( t ).key() == get<1>( t ).key() ); std::printf( "The result is %f for key %d\n", get<0>( t ).value() + get<1>( t ).value(), get<0>( t ).key() ); } ); join_node< tuple<MyMessage, MyMessage>, key_matching<int> > jn( g ); make_edge( f1, input_port<0>( jn ) ); make_edge( f2, input_port<1>( jn ) ); make_edge( jn, f3 ); f1.try_put( 1 ); f1.try_put( 2 ); f2.try_put( 2 ); f2.try_put( 1 ); g.wait_for_all(); }この例で、キー一致 join_node は同じキーのメッセージをペアにするために使用されます。join_node は、型指定メッセージキー拡張を使用し、MyMessage::key メソッドを呼び出してキーを取得します。