0

つまり、shared_ptr タイプを提供するデータ ソースがあります。このポインターは、source_node のオペレーター オーバーロードの範囲外にあるようです。問題を示す完全に単純化された例を追加しました。

私の質問: この問題を克服するエレガントな理由は何ですか?

#include <exception>
#include <tbb/concurrent_queue.h>
#include <tbb/flow_graph.h>
#include <condition_variable>
#include <thread>
#include <chrono>
#include <memory>
#include <iostream>

using namespace tbb::flow;

// Plain Data Object
class Data
{
public:
    size_t _data;
    Data(size_t d) : _data(d){}

};


// simpel counting node
class CountingNode
{
private:
    size_t _count;
public:
    CountingNode():_count(0){}
    size_t operator()(std::shared_ptr<Data> data)
    {
        if (static_cast<bool>(data)) // <-- PROBLEM always false
            _count += data->_data;

        std::cout << _count << std::endl;
        return _count;
    }
    size_t count() { return _count;}
};

// Source,
// exhausted when a empty/null shared_ptr is encountered
// our datasource provides a shared_ptr to a data object
class SourceNode
{
public:

    std::shared_ptr<tbb::concurrent_bounded_queue<std::shared_ptr<Data>>> _queue;
    std::shared_ptr<std::mutex> _mtx;
    bool _started;

    SourceNode() : _started(false)
    {
        _queue = std::shared_ptr<tbb::concurrent_bounded_queue<std::shared_ptr<Data>>>(new tbb::concurrent_bounded_queue<std::shared_ptr<Data>>());
        _mtx = std::shared_ptr<std::mutex>(new std::mutex());
    }

    SourceNode(const SourceNode& other)
    {
        _queue = other._queue;
        _mtx = other._mtx;
        _started = other._started;
    }

    void push(std::shared_ptr<Data> data)
    {
        _queue->push(data);
    }

    bool operator ()(std::shared_ptr<Data> data)
    {
        std::unique_lock<std::mutex> ul(*_mtx);
        {
            if (!_started)
            {
                _started = true;
                for(size_t idx = 0; idx != 10; ++idx)
                    _queue->push(std::shared_ptr<Data>(new Data(idx)));

                _queue->push(std::shared_ptr<Data>()); // no more data
            }
        }

        _queue->pop(data);
        return static_cast<bool>(data);
    }

    void close()
    {
        _queue->push(std::shared_ptr<Data>());
    }
};




int main(int argc, char* argv[])
{
    graph g;
    source_node<std::shared_ptr<Data>> source(g,SourceNode(),false);
    function_node<std::shared_ptr<Data>,int> sink(g,tbb::flow::serial, CountingNode());
    make_edge(source, sink );

    source.activate();
    g.wait_for_all();

    return 0;
}

詳細を提供する必要がある場合は、お知らせください。

敬具 Auke-Dirk

ここに画像の説明を入力

4

1 に答える 1

1

data参照によって渡された引数を受け入れSourceNodeて、更新された値を呼び出し元に返す必要があります。

class SourceNode
{
    ...
    bool operator ()(std::shared_ptr<Data>& data)
    {
        ...
        _queue->pop(data);
        return static_cast<bool>(data);
    }
}

dataそれ以外の場合、オペレーターによって更新された場合はパラメーターのローカル コピーのみが作成され、デフォルトで構築された (空の) 値に対して追加のアクションが実行されます。

于 2015-05-27T12:11:18.327 に答える