我需要一个std :: bind的函数包装器,它将在函数包装器之前调用,将参数传递给包装函数。
std::function<void (int)> foo = postbind<int>(service, handle);
我到目前为止已经开始了
std::function<void (int)> foo = postbind(service, handle);
如何删除该模板参数?它似乎归结为对象生成函数(postbind)的类型推导不够智能。
#include <functional>
template<typename T>
void foo(std::function<void (T)> func)
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
说错误:没有匹配函数来调用'foo(void(&amp;)(int))'
然而,代码示例:
template<typename T>
void foo(T t)
{
}
int main()
{
foo(99);
return 0;
}
这很有效。任何想法如何使这项工作?我需要能够将std :: bind传递给它并将结果成功转换为std :: function。
如何删除模板参数?感谢。
Q值。什么是服务,本课程意味着什么?
一个。封装一个函数包装器,它将boost :: asio :: io_service-&gt;发布到当前线程之外。
完整源代码:
#include <iostream>
#include <functional>
#include <memory>
class io_service
{
};
typedef std::shared_ptr<io_service> service_ptr;
template <typename Arg1>
class postbind_impl_1
{
public:
typedef std::function<void (Arg1)> function;
postbind_impl_1(service_ptr service, function memfunc)
: service_(service), memfunc_(memfunc)
{
}
void operator()(Arg1 arg1)
{
// do stuff using io_service
memfunc_(arg1);
}
private:
service_ptr service_;
function memfunc_;
};
template <typename Arg1>
postbind_impl_1<Arg1> postbind(service_ptr service,
typename postbind_impl_1<Arg1>::function handle)
{
return postbind_impl_1<Arg1>(service, handle);
}
// ----------------
void handle(int x)
{
std::cout << x << "\n";
}
int main()
{
service_ptr service;
std::function<void (int)> foo = postbind(service, handle);
foo(110);
return 0;
}
答案 0 :(得分:3)
绑定表达式的AFAICT参数类型是不可推导的,所以你想要的几乎是不可能的。
答案 1 :(得分:2)
您希望编译器如何知道使用std::function
?在这段代码中:
#include <functional>
template<typename T>
void foo(T func)
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
T
不是std::function<void (int)>
。它是void (&)(int)
(如所说的错误信息),是对函数的引用,而不是函子对象。
传递函数的参数类型的推导应该有效,请尝试:
#include <functional>
template<typename T>
std::function<void (T)> foo(void (*func)(T))
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
如果需要从std::function
或普通函数指针中提取参数类型,则需要一个辅助结构:
template<typename>
struct getarg {};
template<typename TArg>
struct getarg<std::function<void (TArg)>> { typedef TArg type; };
template<typename TArg>
struct getarg<void (*)(TArg)> { typedef TArg type; };
template<typename TArg>
struct getarg<void (&)(TArg)> { typedef TArg type; };
template<typename T>
std::function<void (typename getarg<T>::type)> foo(T func)
{
}
void handler(int x)
{
}
int main()
{
foo(handler);
return 0;
}
使用C ++ 0x,您还可以匹配隐式转换为std::function
的任何内容,包括来自std::bind
和lambdas的返回值:http://ideone.com/6pbCC
答案 2 :(得分:0)
我不完全确定你想要实现的目标,但这是一个存储行动列表的天真包装:
template <typename R, typename A>
struct wrap
{
typedef std::function<R(A)> func;
wrap(func f_) : f(f_) { }
void prebind(func g) { prebound.push_back(g); }
R operator()(A arg)
{
for (auto it = prebound.cbegin(); it != prebound.cend(); ++it)
{
func g = *it;
g(arg);
}
f(arg);
}
private:
std::vector<func> prebound;
func f;
};
wrap<void, int> make_wrap(std::function<void(int)> f)
{
return wrap<void, int>(f);
}
用法:
auto foowrap = make_wrap(foo);
foowrap.prebind(std::function<void(int)>(action1);
foowrap.prebind(std::function<void(int)>(action2);
foowrap(12); // calls action1(12), action2(12), foo(12)
答案 3 :(得分:0)
对所有说不可能的反对者:)
/*
* Defines a function decorator ala Python
*
* void foo(int x, int y);
* function<void ()> wrapper(function<void (int)> f);
*
* auto f = decorator(wrapper, bind(foo, 110, _1));
* f();
*/
#include <functional>
template <typename Wrapper, typename Functor>
struct decorator_dispatch
{
Wrapper wrapper;
Functor functor;
template <typename... Args>
auto operator()(Args&&... args)
-> decltype(wrapper(functor)(std::forward<Args>(args)...))
{
return wrapper(functor)(std::forward<Args>(args)...);
}
};
template <typename Wrapper, typename Functor>
decorator_dispatch<
Wrapper,
typename std::decay<Functor>::type
>
decorator(Wrapper&& wrapper, Functor&& functor)
{
return {wrapper, functor};
}