#include <iostream>
#include <type_traits>
struct Test
{
void f();
template<typename T>
using verify = typename std::enable_if<std::is_same<T, T>::value, T>::type;
template<typename T, typename R, typename... Args>
using MFP = R (verify<T>::*)(Args...);
template<typename T, typename R, typename... Args>
static MFP<T, R, Args...> g(MFP<T, R, Args...> mf){return mf;}
};
int main()
{
auto test = Test::g(&Test::f);
}
prog.cpp: In function ‘int main()’:
prog.cpp:17:30: error: no matching function for call to ‘Test::g(void (Test::*)())’
auto test = Test::g(&Test::f);
^
prog.cpp:17:30: note: candidate is:
prog.cpp:12:28: note: template<class T, class R, class ... Args> static R (std::enable_if<std::is_same<_Tp, _Tp>::value, T>::type::* Test::g(Test::MFP<T, R, Args ...>))(Args ...)
static MFP<T, R, Args...> g(MFP<T, R, Args...> mf){return mf;}
^
prog.cpp:12:28: note: template argument deduction/substitution failed:
prog.cpp:17:30: note: couldn't deduce template parameter ‘T’
auto test = Test::g(&Test::f);
^
Obviously in my real code I am not using std::is_same<T, T>, I'm actually using std::is_base_of, but the issue is that if I use verify at all the compiler fails to deduce the class type.
It is trying to match "Test" with "verify<T>" and it can't deduce the type of T from that (the type can't be deduced until the value of T is know so it may not equal "void" [such in the case where it fails]). You could try moving the verification outside of the g function.