views:

336

answers:

2

I get an incomplete type error when trying to compile my code. I know that it is related to includes, but my project is large and it uses several templates so I can't find which type is actually incomplete. The error message doesn't help either:

Compiling: ../../../addons/ofxTableGestures/src/Graphics/objects/CursorFeedback.cpp
In file included from ../../../addons/ofxTableGestures/ext/boost/fusion/include/invoke_procedure.hpp:10,
                 from ../../../addons/ofxTableGestures/src/oscGestures/tuioApp.hpp:46,
                 from /home/thechaos/Projectes/of_preRelease_v0061_linux_FAT/addons/../apps/OF-TangibleFramework/ofxTableGestures/src/Graphics/objects/CursorFeedback.hpp:35,
                 from /home/thechaos/Projectes/of_preRelease_v0061_linux_FAT/addons/../apps/OF-TangibleFramework/ofxTableGestures/src/Graphics/objects/CursorFeedback.cpp:31:
../../../addons/ofxTableGestures/ext/boost/fusion/functional/invocation/invoke_procedure.hpp: In function ‘void boost::fusion::invoke_procedure(Function, const Sequence&) [with Function = void (tuio::CanBasicFingers<Graphic>::*)(long int, float, float, float, float, float), Sequence = boost::fusion::joint_view<boost::fusion::joint_view<boost::fusion::iterator_range<boost::fusion::vector_iterator<const boost::fusion::vector6<long int, float, float, float, float, float>, 0>, boost::fusion::vector_iterator<boost::fusion::vector6<long int, float, float, float, float, float>, 0> >, const boost::fusion::single_view<tuio::CanBasicFingers<Graphic>*> >, boost::fusion::iterator_range<boost::fusion::vector_iterator<boost::fusion::vector6<long int, float, float, float, float, float>, 0>, boost::fusion::vector_iterator<const boost::fusion::vector6<long int, float, float, float, float, float>, 6> > >]’:
../../../addons/ofxTableGestures/src/oscGestures/tuioApp.hpp:122:   instantiated from ‘void tuio::AlternateCallback<C, M, E>::run(tuio::TEvent*) [with C = tuio::CanBasicFingers<Graphic>, M = void (tuio::CanBasicFingers<Graphic>::*)(long int, float, float, float, float, float), E = tuio::TeventBasicFingersMoveFinger]’
/home/thechaos/Projectes/of_preRelease_v0061_linux_FAT/addons/../apps/OF-TangibleFramework/ofxTableGestures/src/Graphics/objects/CursorFeedback.cpp:64:   instantiated from here
../../../addons/ofxTableGestures/ext/boost/fusion/functional/invocation/invoke_procedure.hpp:88: error: incomplete type ‘boost::fusion::detail::invoke_procedure_impl<void (tuio::CanBasicFingers<Graphic>::*)(long int, float, float, float, float, float), const boost::fusion::joint_view<boost::fusion::joint_view<boost::fusion::iterator_range<boost::fusion::vector_iterator<const boost::fusion::vector6<long int, float, float, float, float, float>, 0>, boost::fusion::vector_iterator<boost::fusion::vector6<long int, float, float, float, float, float>, 0> >, const boost::fusion::single_view<tuio::CanBasicFingers<Graphic>*> >, boost::fusion::iterator_range<boost::fusion::vector_iterator<boost::fusion::vector6<long int, float, float, float, float, float>, 0>, boost::fusion::vector_iterator<const boost::fusion::vector6<long int, float, float, float, float, float>, 6> > >, 7, true, false>’ used in nested name specifier

If I copy the conflictive code to a same file I can compile it. So I know that the code itself is OK, the problem is the way I instantiate it.

How can I trace the origin of this error? Is there any way to get the trace of the c++ compiler and preprocessor to get more informative messages?

edit: I am using gcc 4.4.1

A: 

The type appears to be (from the last line of the error):

boost::fusion::detail::invoke_procedure_impl<void (tuio::CanBasicFingers<Graphic>::*)(long int, float, float, float, float, float), const boost::fusion::joint_view<boost::fusion::joint_view<boost::fusion::iterator_range<boost::fusion::vector_iterator<const boost::fusion::vector6<long int, float, float, float, float, float>, 0>, boost::fusion::vector_iterator<boost::fusion::vector6<long int, float, float, float, float, float>, 0> >, const boost::fusion::single_view<tuio::CanBasicFingers<Graphic>*> >, boost::fusion::iterator_range<boost::fusion::vector_iterator<boost::fusion::vector6<long int, float, float, float, float, float>, 0>, boost::fusion::vector_iterator<const boost::fusion::vector6<long int, float, float, float, float, float>, 6> > >, 7, true, false>

This gives us some possibilities of which I might suspect tuio::CanBasicFingers<> since the include chain contains tuioApp.hpp. If tuio::CanBasicFingers hasn't been defined yet by the time of the instantiation within tuioApp.hpp, you'd get the error.

Mark B
It is definitively related to `tuio::CanBasicFingers<>`. In its constructor I instantiate another template(which is the holder of invoke_procedure) which takes `CanBasicFingers` as a template argument. But I used this type of pattern before whith apparent success. If I comment this instantiation it compiles. However I do not see how to create this object after fully define `CanBasicFingers`.
ChAoS
+2  A: 

It would be easier if you gave us the compiler.

On gcc you can see the preprocessed file using the -E option. If you try compiling the preprocessed file it should get much easier to diagnose. Furthermore you'll see exactly what are the types involved.

As for the specific error, the last line is generally the one indicative:

boost::fusion::detail::invoke_procedure_impl<
  void (tuio::CanBasicFingers<Graphic>::*)
       (long int, float, float, float, float, float),
  const boost::fusion::joint_view<

    boost::fusion::joint_view<
      boost::fusion::iterator_range<
        boost::fusion::vector_iterator<
           const boost::fusion::vector6<long int, float, float, float, float,
              float>,
           0
        >,
        boost::fusion::vector_iterator<
          boost::fusion::vector6<long int, float, float, float, float, float>,
          0
        >
      >,
      const boost::fusion::single_view< tuio::CanBasicFingers<Graphic>* >
    >, // joint_view

    boost::fusion::iterator_range<
      boost::fusion::vector_iterator<
        boost::fusion::vector6<long int, float, float, float, float, float>, 0
      >,
      boost::fusion::vector_iterator<
        const boost::fusion::vector6<long int, float, float, float, float,
            float>,
        6
      >
    > // iterator_range

  >,
  7,
  true,
  false
>

Okay, so reformatting helps a bit here.

It seems that you have a namespace tuio which should contain a template class CanBasicFingers of which you'd like to use the Graphic instanciation and obtain a pointer to a member function.

Assuming you've got all the Boost.Fusion includes right, chances are either CanBasicFingers or Graphic are not included correctly.

Otherwise, lookup the mix in the constness of the iterators: the ranges are defined each with a const and a non-const iterator which is downright strange.

You should try and invoke them separately.

As a general technic for diagnosis, I can only recommend Divide And Conquer approaches. You should try to build up the expression little by little:

namespace fusion = boost::fusion;

// First
typedef void (tuio::CanBasicFingers<Graphic>::* function_t)
    (long int, float, float, float, float, float);

// Second
typedef fusion::vector6<long int, float, float, float, float, float> vector_t;

// Third: the iterators
typedef fusion::vector_iterator< const vector_t, 0 > const_iterator_begin;
typedef fusion::vector_iterator< const vector_t, 6 > const_iterator_end;

typedef fusion::vector_iterator< vector_t, 0 > iterator_begin;
typedef fusion::vector_iterator< vector_t, 6 > iterator_end;

// Fourth: the ranges
// (which const-ness are oddly messed up)
typedef fusion::iterator_range< const_iterator_begin, iterator_end > range_1;
typedef fusion::iterator_range< iterator_begin, const_iterator_end > range_2;

// Fifth the views
typedef const fusion::single_view<tuio::CanBasicFingers<Graphic>*> single_view;
typedef fusion::joint_view< range_1, single_view > joint_view_internal;
typedef fusion::joint_view< joint_view_internal, range_2 > joint_view_external;

// and here is the final type (aaaah!)
typedef fusion::detail::invoke_procedure_impl<
  function_t,
  joint_view_external,
  7,
  true,
  false
> procedure_type;

Compiling this decomposed form, should yield the error at a more precise location :)

Matthieu M.
I am using g++ 4.4.1. Matthieu M., That's Absolutely genius! I will try to use this approach to locate the problem!
ChAoS