次の構造のコードがあります。
template <typename T>
struct Foo
{
struct Bar
{
int data;
};
};
型が Foo か Bar かを教えてくれるメタ関数を書きたいと思っています。最初のものは簡単です:
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> ));
ただし、同じアプローチは Bar では機能しません。
template <typename T>
struct is_bar : boost::mpl::false_
{};
template <typename T>
struct is_bar<typename Foo<T>::Bar> : boost::mpl::true_
{};
このコードはコンパイラによって拒否されます。GCC 言います:
main.cpp:38:8: error: template parameters not used in partial specialization:
main.cpp:38:8: error: ‘T’
奇妙なことに、clang はコードをコンパイルしますが、警告を発行し、メタ関数は機能しません (常に 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>
^
この問題の回避策はありますか? C++11 固有のソリューションで問題ありません。