Как передать перегруженную функцию оператору?

мне нужно передать функции оператора. Любая унарная функция, имеющая правильный тип 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);
};