C++ tbb flow graph, multifunction_node giving incomplete type error

260 views Asked by At

Far as I understand, incomplete type error happens when there's forward declaration without full specification of type, then instantiate that type since the compiler can't tell the size of such type. In my case I don't understand how this code produces such a problem. For simplicity I've removed unrelated parts.

class FilterOnNode {
   struct PartialResult { int n1,n2; long e; };
   typedef PartialResult* InputResult;
   typedef tbb::flow::multifunction_node<InputResult, InputResult> FilterNodeType;

   void BuildGraph(tbb::flow::graph &g, tbb::flow::graph_node &src) {
       auto sampleNode = FilterNodeType(
                g,
                tbb::flow::concurrency::unlimited,
                [&](const InputResult &input, typename FilterNodeType::output_ports_type &op) { //error points to here
                    //some logic here... might not send message.
                    std::get<0>(op).try_put(input);
                });
       tbb::flow::make_edge(src, sampleNode);
       //create couple other nodes like previous then connect edges
       tbb::flow::make_edge(tbb::flow::output_port<0>(sampleNode), otherNode);
   }

compiler is giving error of incomplete type at the lambda expression. Exact error says:

/usr/local/include/tbb/flow_graph.h:1568:7: error: incomplete type β€˜std::tuple_size<FilterOnNode::PartialResult*>’ used in nested name specifier class multifunction_node

Isn't the type PartialResult fully specified already? Tried taking it out of the class but still same problem.

1

There are 1 answers

1
JaMiT On BEST ANSWER

Isn't the type PartialResult fully specified already?

Yes, but that is not what the error message complains about. The error message should be read as "error: incomplete type β€˜[name of the incomplete type]’ used [place where it is used]". The incomplete type is std::tuple_size<FilterOnNode::PartialResult*>, not PartialResult. There is no definition of std::tuple_size<T> when T is a pointer (e.g. PartialResult*).

The location of the use of the incomplete type has something to do with class multifunction_node. I looked around for the header defining this and found the following. (I don't know why this information was not in the API documentation that I found.)

tbb/flow_graph.h, beginning of the definition of multifunction_node:

//! implements a function node that supports Input -> (set of outputs)
// Output is a tuple of output types.
template<typename Input, typename Output, typename Policy = queueing>
class multifunction_node :

So the Output parameter has to be a tuple of output types, yet you supplied a raw output type. Try changing your definition of FilterNodeType to the following.

typedef tbb::flow::multifunction_node<InputResult, std::tuple<InputResult>> FilterNodeType;
//                                                 ^^^^^^^^^^^           ^

It might be possible to replace std::tuple with tbb::flow::tuple, but I did not look into how the TBB tuple is to be used.