Solving a difficult incomplete type error
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
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 :)
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.
精彩评论