メンバー関数ポインター型の戻り値の型に基づいて、クラス テンプレート 'special' を特殊化しようとする次のコードは、VC9 でコンパイル エラーになります。
template<class F> struct special {};
template<class C> struct special<void(C::*)()> {};
template<class R, class C> struct special<R(C::*)()> {};
struct s {};
int main()
{
special<void(s::*)()> instance;
return 0;
}
エラー C2752: 'special': 複数の部分的な特殊化がテンプレート引数リストと一致します
http://ideone.com/ekWGg で示されているように、同じコードが GCC-4.3.4 で受け入れられて
います。
ただし、私は恐ろしく煩わしい回避策を考え出しました(少なくともこの特定のユースケースでは。より一般的な解決策を歓迎します):
#include <boost/function_types/result_type.hpp>
#include <boost/type_traits/is_same.hpp>
template<typename F, typename R>
struct is_result_same :
boost::is_same<
typename boost::function_types::result_type<F>::type,
R
>
{};
template<class F, bool = is_result_same<F, void>::value>
struct special {};
template<class R, class C> struct special<R(C::*)(), true> {};
template<class R, class C> struct special<R(C::*)(), false> {};