I was looking through some code (PCL) and found this define directive:
#define PCL_FEATURE_POINT_TYPES \
(pcl::PFHSignature125) \
(pcl::PFHRGBSignature250) \
(pcl::PPFSignature) \
(pcl::PPFRGBSignature) \
(pcl::NormalBasedSignature12) \
(pcl::FPFHSignature33) \
(pcl::VFHSignature308) \
(pcl::Narf36)
Can someone explain to me what this is doing (and possibly provide a reference to this feature?). When would something like this be useful?
Oh boy, this is messed up.
Short version
It's a list-like structure (a "sequence" in Boost PP parlance) for the preprocessor, used by the Boost Preprocessor Macros (=black magic); all the
PCL_*_POINT_TYPES
macros are to be used with thePCL_INSTANTIATE
macro to provide (via convoluted means) explicit instantiations of some templates for the types given in the sequence.Long version
Disclaimer: I don't have any specific expertise about PCL, I just grepped around a lot; all references to the code are relative to PCL SVN r8781.
It seems to work like this:
all the
PCL_*_POINT_TYPES
are macros intended to be used with the PCL_INSTANTIATE macro;this macro uses the Boost macro
BOOST_PP_SEQ_FOR_EACH
to extract each element from that "sequence", and feed it toPCL_INSTANTIATE_IMPL
:PCL_INSTANTIATE_IMPL
, in turn, usesBOOST_PP_CAT
to concatenatePCL_INSTANTIATE_
with theTEMPLATE
parameter ofPCL_INSTANTIATE
. and sticks the point type (i.e. the one extracted from the list of thePCL_*_POINT_TYPES
macro) after it, in parentheses.So, when writing
(taken from here, line 43)
what actually happens is
Now,
PCL_INSTANTIATE_Search
(and all its siblingsPCL_INSTANTIATE_T
where T is the argument toPCL_INSTANTIATE
) are in turn other macros, defined elsewhere. Such macros typically expand to explicit template instantiations:(from here, line 208; notice the semicolon at the end of the macro)
In the end, it becomes:
(newlines added)
Thus, the whole thing boils down to a series of explicit template instantiations.
To sum up again:
PCL_*_POINT_TYPES
is a "preprocessor list" of types to be used withPCL_INSTANTIATE
;PCL_INSTANTIATE
takes the list, and, with strange sorceries, instantiates the template relative to the specified suffix (e.g.Search
in this case) for all the types in the list.So, AFAICT, the whole point of this thing is to provide a concise mean to explicitly instantiate a template class over all the specified types. I didn't look further, but I suppose that this is done to avoid the need of "normal" ("on the spot") templates expansions in the code that uses the library, maybe to speed up compilation times, to limit the possible templates expansions only to those definite types, to keep them in a shared library (to keep down the client executable size), or for something even different.