Обходной путь, позволяющий tr1 :: function проглотить возвращаемые значения - PullRequest
1 голос
/ 11 июля 2011

Как продолжение Может ли tr1 :: function глотать возвращаемые значения? , как можно обойти ограничение, что tr1::function не может глотать возвращаемые значения?

Это должно работать в конкретном случае проглатывания возвращаемого значения вызываемого объекта без аргументов:

template<typename FuncT>
struct swallow_return_t
{
  explicit swallow_return_t(FuncT i_Func):m_Func(i_Func){}
  void operator()(){ m_Func(); }
  FuncT m_Func;
};

template<typename FuncT>
swallow_return_t<FuncT>
swallow_return(FuncT f)
{
  return swallow_return_t<FuncT>(f);
}

Тогда используйте как:

int Foo();
std::tr1::function<void()> Bar = swallow_return(Foo);

Я предполагаю, что шаблоны с переменными значениями и совершенная пересылка позволят обобщить эту технику на произвольные списки параметров. Есть ли лучший способ?

1 Ответ

0 голосов
/ 11 июля 2011

В GCC 4.6.1 у меня работает следующее:

#include <functional>

int foo() { return 5; }
int goo(double, char) { return 5; }

int main()
{
  std::function<void()> f = foo;
  std::function<void(float, int)> g = goo;
  (void)f();
  (void)g(1.0f, 'a');
}

Вот обертка, использующая лямбды, но она еще не автоматизирована

template <typename T, typename ...Args>
struct strip_return
{
  static inline std::function<void(Args...)> make_function(std::function<T(Args...)> f)
  {
    return [&f](Args... args) -> void { f(args...); };
  }
};

int main()
{
  auto q = strip_return<int>::make_function(std::bind(foo));
  q();
}

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

template <typename T, typename ...Args>
static inline std::function<void(Args...)> make_direct(T (&f)(Args...))
{
  return [&f](Args... args) -> void { f(args...); };
}

int main()
{
  auto p = make_direct(foo);
  q();
}
...