template<typename Signature>
class myfunction //basic class template
{
};
template<typename R, typename... Args>
class myfunction<R (Args...)> //normal function specialized edition
{
typedef R (*Ptr)(Args...);
Ptr m_p;
public:
myfunction(Ptr p) : m_p(p)
{
}
R operator()(Args... args)
{
return m_p(args...);
}
};
template<typename R, typename T, typename ... Args>
class myfunction<R (T*, Args...)> //member function specialized edition one
{
typedef R (T::* mPtr)(Args...);
mPtr m_p;
public:
myfunction(mPtr p): m_p(p)
{
}
R operator()(T* likeThis, Args...args)
{
return (likeThis->*m_p)(args...);
}
};
template<typename R, typename T, typename ... Args>
class myfunction<R (T, Args...)> //member function specialized edition two
{
typedef R (T::* mPtr)(Args...);
mPtr m_p;
public:
myfunction(mPtr p): m_p(p)
{
}
R operator()(T likeThis, Args...args)
{
return (likeThis.*m_p)(args...);
}
};
template<typename R, typename T, typename ... Args>
class myfunction<R(T&, Args...)> //member function specialized edition three
{
typedef R (T::* mPtr)(Args...);
mPtr m_p;
public:
myfunction(mPtr p): m_p(p)
{
}
R operator()(T& likeThis, Args...args)
{
return (likeThis.*m_p)(args...);
}
};
int func1()
{
cout << "func1";
return 0;
}
void func2(int x)
{
cout << "func2";
cout << x ;
}
int main()
{
myfunction<int(void)> f1(func1);
f1();
myfunction<void(int)> f2(func2);//this will fail, why?
f2(1);
return 0;
}
Я хочу смягчить функцию обертки в стандартной библиотеке. Тест-код аналогичен приведенному выше. Тем не менее, f1 может считать правильное, это стандартная специализированная редакция. В то время как f2 сначала соответствует специальной функции-члене, но после неудачи сопоставления, она должна идти в соответствие с обычной специализированной редакцией, а затем преуспеть? Это именно то, что означает SFINAE, верно? После того, как я прокомментирую функцию-член, специализированную редакцию второй, она соответствует одной воле, почему? , пожалуйста, помогите мне.Выбор шаблона и SFINAE?
Проблема заключается в том, что ваши специализации специализированы для обычной функции с хотя бы одним аргументом, а не с функциями-членами. Измените специализацию на нечто вроде 'template stuct Foo ;'. Также имейте в виду, что cv квалифицированные функции или функции члена с различными соглашениями о вызовах имеют разные подписи. –
Хорошо, спасибо за ваш ответ. Я знаю, что это может работать: template class myfunction .when я хочу обернуть класс функций-членов Myclass { public: int f (int x) { cout << "функция-член!" << x << endl; return 0; } }; Я должен написать вот так: Myclass obj; myfunction f3 (& Myclass :: f); f3 (obj, 3); Я хочу сохранить последовательность и написать как myfunction f3 (& Myclass :: f); как я могу это сделать :? –