问题
As a follow-up to Can tr1::function swallow return values?, how can one work around the limitation that tr1::function
cannot swallow return values?
This should work in the specific case of swallowing the return value of a callable object taking no arguments:
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);
}
Then use like:
int Foo();
std::tr1::function<void()> Bar = swallow_return(Foo);
I assume variadic templates and perfect forwarding would permit generalization of this technique to arbitrary parameter lists. Is there a better way?
回答1:
The following works for me in 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');
}
Here's a wrapper using lambdas, but it's not automagic yet
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();
}
Forget the middle part. OK, since std::function
is type-erasing, it's hard to get at the underlying types. However, if you go for the function reference directly, you can avoid these problems entirely:
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();
}
来源:https://stackoverflow.com/questions/6653531/workaround-to-allow-tr1function-to-swallow-return-values