get std :: function для вывода передачи по ссылке / передаче по значению - PullRequest
0 голосов
/ 11 сентября 2018

Я пишу шаблонную функцию, которая принимает std :: function в качестве входных данных и выполняет некоторую обработку функции.Мне нужен способ автоматической обработки любой функции, но у меня возникают проблемы с передачей по ссылке при выводе типа.

Тип функций, которые я использую, является общим, список аргументов также различается.типы.Вот репродуктор

#include <iostream>
#include <chrono> //c++11
#include <functional> //c++11

using namespace std;
// for use with functions passing by value
  template<typename T_Out, typename... T_Args>
    inline int get_stats( T_Out f(T_Args...), T_Args&... args)
    {
      f(args...);
      return 0;
    }

int foo(int x, double y)
{ return 0; }

int goo(int& x, double& y)
{ return 0; }

int hoo(int x , double& y)
{ return 0; }


int main()
{

  int x = 42;
  double y = 0.0;
  cout << get_stats( foo, x, y) << endl;

  return 0;
}

Приведенный выше шаблон работает на foo, и я могу заставить hoo работать, если заменить f(T_Args...) на f(T_Args&...), но я не могу получить hooработать без явного написания шаблона, соответствующего типу передачи, который в тот момент я мог бы вообще не использовать шаблоны.

Как я могу автоматически обрабатывать тип передачи?Кроме того, было бы неплохо иметь возможность автоматически обрабатывать prvalues.Я хотел бы ограничить это до c ++ 11, если это возможно.

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018
template<typename T_Func, typename ...T_Args>
inline int get_stats(T_Func f, T_Args&&... args)
{
    return f(args...);
}

int foo(int x, double y)
{ return x + y; }

int goo(int& x, double& y)
{ return x - y; }

int hoo(int x , double& y)
{ return x * y; }


int main()
{

    int x = 42;
    double y = 1.5;
    cout << get_stats(foo, x, y) << endl;
    cout << get_stats(goo, x, y) << endl;
    cout << get_stats(hoo, x, y) << endl;

    return 0;
}
0 голосов
/ 12 сентября 2018

на самом деле вам нужно объединить два предыдущих ответа. Ответ КорелК, чтобы не пытаться определить точную сигнатуру переданного функтора, и ответ CJ13 на использование совершенной пересылки:

template<typename T_Func, typename ...T_Args>
inline int get_stats(T_Func f, T_Args&&... args)
{
    return f(std::forward<T_Args>(args)...);
}

Интернет

0 голосов
/ 12 сентября 2018

Отредактировано в ответ на лучшее решение:

То, что вы хотите использовать здесь, это то, что Скотт Мейерс называет универсальной ссылкой:

template<typename T_Out, typename... T_Args>
inline T_Out get_stats( T_Out f, T_Args&&... args)
{
  return f(std::forward<T_Args>(args)...);
}

Когда за параметром шаблона следует двойной амперсанд, это будет либо ссылка lvalue, либо ссылка rvalue в зависимости от того, что вы передаете.Затем вы вызываете std :: forward, что будет продолжать использовать правильную ссылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...