struct A // some class
{
void method(); // non-static member method
static void function(); // static member method
};
void function(); // global function
vector<A> vi; // any such `std` like container
Я хочу иметь функцию (скажем, Iterate()
) который можно назвать ниже:
Iterate(vi, &A::method); // (1)
Iterate(vi, &A::function); // (2a)
Iterate(vi, &function); // (2b)
(2a) и (2b) просто идентичны.
Сейчас Iterate()
Прототип выглядит следующим образом для (1) и (2):
template<typename Container, typename Method>
void Iterate (Container &container, Method method); // for (1)
template<typename Container, typename Function>
void Iterate (Container &container, Function function); // for (2a), (2b)
Естественно, что оба абсолютно одинаковы, что приводит к ошибке компиляции.
Есть ли способ перегрузить / специализировать Iterate()
в C ++ 03, который позволит обе функции сосуществовать?
Вы можете сделать одну функцию более конкретной, чем другую:
template<typename Container, typename Functor>
void Iterate (Container &container, Functor fun);
template<typename Container, typename R, typename ..Args>
void Iterate (Container &container, R (Container::value_type::*fun)(Args...));
Первый шаблон будет работать для обычных функций, объектов-функций и статических функций-членов, а второй — только для нестатических функций-членов.
В C ++ 03 вы можете смоделировать шаблон с переменными параметрами, написав перегрузки, как показано здесь:
template<typename Container, typename R>
void Iterate (Container &container, R (Container::value_type::*fun)());
template<typename Container, typename R, typename Arg>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg));
template<typename Container, typename R, typename Arg1, typename Arg2>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg1, Arg2));
//add more overloads to handle member functions
//that take 3 or more arguments
Конечно, если вам нужно реализовать их по-другому. Например, синтаксис для вызова функции-члена будет (obj.*fun)(a1,a2,a3);
в то время как синтаксис вызова функтора просто fun(a1,a2,a2)
, Я не знаю, какие аргументы вы бы передали функции (член или функтор). Я предполагаю, что это не настоящий код, вы просто хотите изучить синтаксис.
Одним из важных моментов является то, что obj
(из контейнера) есть не необходимо вызвать функтор, но вы можете передать его в качестве аргумента.
Других решений пока нет …