2017-02-20 18 views
2

У меня возникли проблемы с реализацией этого в унаследованном C++, но я уверен, что это можно сделать. Скажем, у меня есть функцию высшего порядка, который нуждается в двух вариантах, один для одинарных (вызываемых объектов функциональных объектов, функции, функции-члены)Отправка бинарных и унарных вызовов в C++ 03

template <class F> 
void ho_fun(F argFun) { 
    int arg1; 
    argFun(arg1); 
} 

и один двоичный:

template <class F> 
void ho_fun(F argFun) { 
    int arg1, arg2; 
    argFun(arg1, arg2); 
} 

Я ищу для полное решение с точки зрения «вызываемого типа» (в противном случае я, очевидно, использовал бы arity из функций для этого), т. е. поддержка функций и объектов функции.

Я переводил this прекрасное сообщение на C++ 03 (удалите ... и using typedefs), но он не работает.

PS. Я не решаю проблему, указанную выше, это всего лишь sscce. Также я упоминаю C++ 03, потому что я работаю над устаревшим кодом для этого проекта, и современное решение мне бесполезно. Во что бы то ни стало, не стесняйтесь публиковать современные, но, пожалуйста, подумайте о том, чтобы помочь мне.

+0

I не понимаю. Код в вопросе не работает, но вы все равно не хотите знать, что с ним не так? – NathanOliver

+0

Правильный способ сделать это - это varadics. Почему вы пытаетесь избавиться от '...' s? –

+0

@NathanOliver Обычно мои примеры ошибочно принимают за фактическую проблему, которую я хочу решить. Фактической проблемой является «отправка для унарного и двоичного кода», я упоминаю PS, чтобы избежать ответов, таких как «передать другой аргумент» или «создать дополнительную перегрузку» –

ответ

1

Этот ответ дает решение вопроса, я понимаю вас спросить:

Как я специализируюсь функцию так, что он может обнаружить, является ли это аргумент одноместной или бинарная функция, метод или функтор?

В вашего единственного варианта, чтобы написать специализации для каждого из них, и, кстати, вам нужно сделать специализации для const методов, а также Непро- const методы:

template <typename Arg, typename Result> 
void ho_fun(Result(*argFun)(Arg)) { 
    Arg arg = 13; 

    argFun(arg); 
} 

template <typename Arg1, typename Arg2, typename Result> 
void ho_fun(Result (*argFun)(Arg1, Arg2)) { 
    Arg1 arg1 = 13; 
    Arg2 arg2 = 42; 

    argFun(arg1, arg2); 
} 

template <typename T, typename Arg, typename Result> 
void ho_fun(Result(T::*argFun)(Arg)) { 
    T myClass; 
    Arg arg = 13; 

    (myClass.*argFun)(arg); 
} 

template <typename T, typename Arg1, typename Arg2, typename Result> 
void ho_fun(Result(T::*argFun)(Arg1, Arg2)) { 
    T myClass; 
    Arg1 arg1 = 13; 
    Arg2 arg2 = 42; 

    (myClass.*argFun)(arg1, arg2); 
} 

template <typename T, typename Arg, typename Result> 
void ho_fun(Result(T::*argFun)(Arg) const) { 
    T myClass; 
    Arg arg = 13; 

    (myClass.*argFun)(arg); 
} 

template <typename T, typename Arg1, typename Arg2, typename Result> 
void ho_fun(Result(T::*argFun)(Arg1, Arg2) const) { 
    T myClass; 
    Arg1 arg1 = 13; 
    Arg2 arg2 = 42; 

    (myClass.*argFun)(arg1, arg2); 
} 

template <class T> 
void ho_fun(T argFun) { 
    ho_fun(&T::operator()); 
} 

Live Example