解决方法允许tr1 :: function吞下返回值

时间:2011-07-11 16:45:57

标签: c++ c++11 tr1

作为Can tr1::function swallow return values?的后续行动,如何解决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 :(得分:0)

以下适用于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');
}

这是一个使用lambdas的包装器,但它不是自动的

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();
}