Boost 1.54 added a new library, Boost.TTI for type traits introspection. The following code using the has_template
functionality, works on g++ but not on Clang
#include <boost/tti/has_template.hpp>
BOOST_TTI_HAS_TEMPLATE(Template1)
BOOST_TTI_HAS_TEMPLATE(Template2)
BOOST_TTI_HAS_TEMPLATE(Template3)
struct Top
{
template <class X> struct Template1 { };
template <typename A,typename B,typename C> class Template2 { };
template <typename A,typename B,typename C,int D> class Template3 { };
};
int main()
{
static_assert( has_template_Template1<Top>::value, ""); // true
static_assert( has_template_Template2<Top>::value, ""); // true
static_assert(!has_template_Template3<Top>::value, ""); // false, not all typename/class template parameters
}
Question: why doesn't this code compile on Clang? According to the Boost.TTI docs, support for variadic macros is required, but Clang has been supporting that since 2.9.
BOOST_TTI_HAS_TEMPLATE
uses variadic macros from Boost.Preprocessor. The maintainer of this library does not want to depend on Boost.Config and also believes that the macro that Config defines is not "strong enough" for a preprocessor metaprogramming library.. For these reasons the use of the variadic versions of BOOST_TTI_HAS_TEMPLATE
depends on whether BOOST_PP_VARIADICS
is defined. Sadly, the code for automatically determining if a compiler has variadic macro support is out of date and does not include clang amongst the compilers for which variadic support is on. The recommended workaround is defining BOOST_PP_VARIADICS=1
.
Apparently this has been solved in trunk, and may possibly be included in a future release.