вывод C++ параметров шаблона класса «нетипового указателя на функцию»

StackOverflow https://stackoverflow.com/questions/368737

Вопрос

Рассмотрим класс шаблона, например:

template<typename ReturnType, ReturnType Fn()>
class Proxy
{
    void run()
    {
        ReturnType ret = Fn();
        // ... do something ...
    }
};

// and a functions
int fn1() { return 5; }
float fn2() { return 5; }

Это можно создать с помощью:

Proxy<int, &fn1> p1;

Но явное объявление типа возвращаемого значения кажется излишним.Я пытаюсь достичь чего-то вроде:

 someProxyInstantation<&fn1> p1;
 someProxyInstantation<&fn2> p2;

К сожалению, я не разбираюсь в C++, и это кажется скрытым уголком языка (по крайней мере, для меня).

Если бы я мог просто перейти от указателя на функцию к ее типу — что-то вроде:std::tr1::result_of<&fn>::type // Ошибка 1 error C2923:'std::tr1::result_of':«fn1» не является допустимым аргументом типа шаблона для параметра «_Fty».

ошибка имеет смысл, поскольку параметр вообще не является «типом»

В C++0x есть decltype(&fn1), но до этого еще много лет.

Есть ли способ сделать это на С++ 03 (+ tr1)?

Ограничения:- Я не хочу передавать функтор, f1 и f2 должны оставаться глобальными функциями, которые имеют возвращаемое значение (не могут переместить его в параметр).)

Это было полезно?

Решение

Это невозможно в C++03.Если вы хотите передать указатель на функцию как параметр, не являющийся типом, компилятор должен знать тип параметра.Поэтому вам необходимо предоставить недостающие части (в данном случае тип возвращаемого значения).Вы можете передать прокси-серверу указатель на функцию в качестве значения во время выполнения и указать его тип в качестве единственного аргумента.Затем вы можете написать функцию-генератор, которая выполняет эту работу:

template<typename T>
Proxy<T> make_proxy(T t) { return Proxy<T>(t); }

К сожалению, в современном C++ вам все равно придется указать тип, чтобы присвоить его автоматической переменной:

Proxy<int(*)()> p = make_proxy(&fn1);

Вы не можете использовать auto p = make_proxy(&fn1); еще.Обратите внимание: если вы хотите использовать тип функции слева, вам необходимо изменить функцию-генератор, чтобы она не предоставляла тип указателя функции:

template<typename T>
Proxy<typename boost::remove_pointer<T>::type> make_proxy(T t) { 
    return Proxy<typename boost::remove_pointer<T>::type>(t); 
}

Теперь вы можете сделать

Proxy<int()> p = make_proxy(&fn1);

используя прокси, теперь вы можете просто сделать

doSomething(make_proxy(&fn1));

А если doSomething является шаблонным или иным образом полиморфным, вам не потребуется знать точный тип функции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top