Как передать перегруженную функцию оператору?
мне нужно передать функции оператора. Любая унарная функция, имеющая правильный тип arg. Возвращаемый тип может быть любым. Поскольку это код библиотеки, я не могу обернуть его или бросить f
к специфической перегрузке (вне operator*
). Функция принимает operator*
1st arg как собственный аргумент. Искусственный пример ниже компилирует и возвращает правильные результаты. Но он жестко закодирован int
return type - для компиляции этого примера.
#include <tuple>
#include <iostream>
using namespace std;
template<typename T>
int operator* (T x, int& (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
cout << tpl * get<0>;
}
можно сделать operator*
принять f
с произвольным типом возврата?
обновление-ошибка GCC? Код:
#include <tuple>
template<typename T, typename U>
U operator* (T x, U& (*f)(T&) ) {
return (*f)(x);
};
int main() {
std::tuple<int,int> tpl(42,43);
return tpl * std::get<0,int,int>;
}
компилирует и работает правильно с gcc462 и 453, но отклоняется с gcc471 и 480. Таким образом, возможно ошибка регрессии GCC. Я отправил отчет об ошибке: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54111
редактировать Я изменил пример использования кортежа как arg - можно было тривиально вывести тип возврата в предыдущем образец.
EDIT2
Многие люди не могли понять, что нужно, поэтому я изменил до operator*
чтобы сделать пример более реальный.
3 ответов
в качестве ответа на ваш обновленный вопрос:
как обсуждалось @DavidRodríguez,get<0>
не хватает, ни syntatically правильно &get<0>
. Что вам нужно, так это &get<0,int,int>
. Следуя вашему примеру, было бы:
#include <tuple>
using namespace std;
template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
call(tpl, &get<0,int,int>);
return 0;
}
при нормальном использовании std::get<>()
, the int,int
часть выводится автоматически. Но в вашей ситуации вам нужно его предоставить, так как нет параметров. Одним из обходных путей является custom get
шаблон функции:
#include <tuple>
using namespace std;
template <size_t I, typename T>
auto myGet(T& tpl) -> decltype(get<I>(tpl))
{
return get<I>(tpl);
}
template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
auto get0 = &myGet<0, decltype(tpl)>;
call(tpl, get0);
// call(tpl, &myGet<0, decltype(tpl)>); // all in one line, do not work
return 0;
}
да, если это что вы имеете в виду:
template<typename T, typename F>
auto call (T x, F f) -> decltype(f(x)) {
return (f)(x);
}
на самом деле есть много способов сделать это.
вы должны быть в состоянии сделать это:
template<typename T,typename U>
U call (T x, U (*f)(T) ) {
return (*f)(x);
};