join_node の型指定メッセージキー

概要

この拡張は、キー一致 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 メソッドを呼び出してキーを取得します。

関連情報