I have code with the following structure:
template <typename T>
struct Foo
{
struct Bar
{
int data;
};
};
I want to write metafunctions which will tell me if a type is either Foo or Bar. The first one is easy:
template <typename T>
struct is_foo : boost::mpl::false_
{};
template <typename T>
struct is_foo<Foo<T> > : boost::mpl::true_
{};
...
BOOST_MPL_ASSERT(( is_foo<Foo<int> > ));
BOOST_MPL_ASSERT_NOT(( is_foo<int> ));
However, the same approach does not work for Bar:
template <typename T>
struct is_bar : boost::mpl::false_
{};
template <typename T>
struct is_bar<typename Foo<T>::Bar> : boost::mpl::true_
{};
This code is rejected by the compiler. GCC says:
main.cpp:38:8: error: template parameters not used in partial specialization:
main.cpp:38:8: error: ‘T’
Oddly, clang will compile the code, but it issues a warning and the metafunction does not work (always false):
main.cpp:38:8: warning: class template partial specialization contains a template parameter that can not be deduced;
this partial specialization will never be used
struct is_bar<typename Foo<T>::Bar> : boost::mpl::true_
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:37:20: note: non-deducible template parameter 'T'
template <typename T>
^
Is there a workaround for this issue? A c++11-specific solution would be fine.