C++11 result_of вывести мой тип функции не удалось

Я пробовал программу ниже:

#include<type_traits>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
int answer() { return 42; }

int main()
{
    call(answer); 
    return 0;
}

"вызов (ответ)" не компилируется

VC говорит, что 'R call(F&)' не может вывести аргумент шаблона для 'R'

GCC сообщает | примечание: вывод / замена аргумента шаблона не удалось:| ошибка: функция, возвращающая функцию

Я не уверен, можно ли использовать "имя функции" для шаблонов. Где я ошибся, как заставить мой звонок (ответ) работать?

3 ответа

Решение

Вы можете использовать переадресацию ссылок в следующих случаях:

#include<type_traits>
#include<utility>
#include<cassert>

using namespace std;

template <class F, class R = typename result_of<F()>::type>
R call(F&& f) { return std::forward<F>(f)(); }

int answer() { return 42; }

int main()
{
    assert(call(answer) == 42);
    return 0;
}

Обычно избегает неприятностей.

Тем не менее, почему ваш код не работает, хорошо объясняется @TC в его ответе.
Смотрите также комментарии к этому вопросу для получения дополнительной информации.

Ты звонишь f как значение, так:

template <class F, class R = typename result_of<F&()>::type>
//                                               ^
R call(F& f) { return f(); }

I suppose you could avoid the second template argument and use a combination of auto а также decltype(),

Что-то вроде

#include<type_traits>

using namespace std;

template <class F>
auto call(F& f) -> decltype( f() )
 { return f(); } 

int answer()
 { return 42; }

int main()
{
    call(answer); 

    return 0;
}

If you (when you) can use C++14, you can use simply auto

template <class F>
auto call(F& f)
 { return f(); } 

PS: извините за мой плохой английский.

Другие вопросы по тегам