[英]automatic conversion from boost::bind_t to boost::function
I have a method of the following signature: 我有一个以下签名的方法:
template<typename T>
void
register_msg_action(const pmt::pmt_t& name,
boost::function<T(pmt::pmt_t)> converter,
boost::function<void(T)> action)
( pmt_t
is a complete type, before you ask) (
pmt_t
是一个完整的类型,在你问之前)
as well as overloads that take T converter(pmt::pmt_t)
and void converter(T)
(ie raw C/C++ functions), as well as all permutations of the above boost::function<>
and the C-style function arguments. 以及采用
T converter(pmt::pmt_t)
和void converter(T)
(即原始C / C ++函数)的重载,以及上述boost::function<>
和C风格函数参数的所有排列。 That leaves me with 4 different methods already. 这让我有4种不同的方法。
I'd like to avoid increasing the number of methods further. 我想避免进一步增加方法的数量。 However, the most common thing I'll do is call something like
但是,我要做的最常见的事情就是打电话
register_msg_action(pmt::mp("key"),
pmt::to_long, /* "raw" function long(pmt_t) */
boost::bind(&my_class::void_method_of_long, this, _1) /* CAVEAT */
);
My approach was that the /* CAVEAT */
argument is implicitly convertible to boost::function<void(T)>
, but however, this doesn't seem to be the case (g++ 5.1.1): 我的方法是
/* CAVEAT */
参数可以隐式转换为boost::function<void(T)>
,但是,似乎并非如此(g ++ 5.1.1):
error: no matching function for call to ‘register_msg_action(pmt::pmt_t, boost::function<long int(boost::intrusive_ptr<pmt::pmt_base>)>&, boost::_bi::bind_t<void, void (*)(long int), boost::_bi::list1<boost::arg<1> > >)’
register_msg_action(pmt::mp("hi"), long_function, boost::bind(&my_class::void_method_of_long, this ,_1));
... all the other candidates (boost::function,boost::function); ...所有其他候选人(boost :: function,boost :: function); (T(pmt_t),boost::function);
(T(pmt_t),升压::功能); (T(pmt_t), void(T)) ...
(T(pmt_t),void(T))......
test.cc:56:1: note: candidate: template<class T> void register_msg_action(const pmt_t&, T (*)(pmt::pmt_t), boost::function<void(T)>)
register_msg_action(const pmt::pmt_t& name,
^
test.cc:56:1: note: template argument deduction/substitution failed:
test.cc:80:76: note: ‘boost::_bi::bind_t<void, void (*)(long int), boost::_bi::list1<boost::arg<1> > >’ is not derived from ‘boost::function<void(T)>’
register_msg_action(pmt::mp("key"), pmt::to_long, boost::bind(&my_class::void_method_of_long, this, _1));
Now, doing 现在,做
boost::function<void(long)> action (boost::bind(&my_class::void_method_of_long, this, _1));
register_msg_action(pmt::mp("key"), pmt::to_long, action);
works beautifully. 工作得很漂亮。 Since there is even a constructor that takes
boost::_bi::bind_t
in boost::function
, I wonder what I must do to make this work, without 因为甚至有一个构造
boost::function
在boost::function
boost::_bi::bind_t
,我想知道我必须做些什么来使这个工作, 没有
boost::function
boost::function
boost:phoenix
for functional programming (would have tried this, but the boost versions we must support don't all have phoenix
yet. boost:phoenix
进行函数式编程(试过这个,但是我们必须支持的boost版本并不是所有的都有phoenix
。 I'm afraid of adding the type of the third argument as additional template typename, because that would break the parameter list type safety that is necessary to guarantee action(converter(pmt::pmt_t))
works, and honestly, I'd rather deal with more code now than examine user's templated g++ errors later on. 我害怕将第三个参数的类型添加为附加的模板类型名称,因为这会破坏保证
action(converter(pmt::pmt_t))
所必需的参数列表类型安全性action(converter(pmt::pmt_t))
,并且老实说,我宁愿现在处理更多代码,而不是稍后检查用户的模板化g ++错误。
The problem is when T
appears in the signature of register_msg_action
within template arguments of boost::function
. 问题是当
T
出现在boost::function
模板参数中的register_msg_action
的签名中时。 Then, if you're not calling it with an actual boost::function
object, it cannot be deduced. 然后,如果你没有使用实际的
boost::function
对象调用它,则无法推断出它。 It should work if you specify the template argument explicitly: 如果您明确指定模板参数,它应该工作:
register_msg_action<long>(pmt::mp("key"),
pmt::to_long, /* "raw" function long(pmt_t) */
boost::bind(&my_class::void_method_of_long, this, _1)
);
If you want to keep the option of deducing T
when using at least one plain-function argument, you have the option to explicitly make the T
non-deducible in its boost::function
use: 如果你想在使用至少一个普通函数参数时保留推导
T
的选项,你可以选择在其boost::function
使用中明确地使T
不可导入:
template <class T>
struct NonDeduced
{
typedef T type;
};
// T has to be specified explicitly at call site
template<typename T>
void
register_msg_action(const pmt::pmt_t& name,
boost::function<typename NonDeduced<T>::type (pmt::pmt_t)> converter,
boost::function<void(typename NonDeduced<T>::type)> action)
// T deducible from converter
template<typename T>
void
register_msg_action(const pmt::pmt_t& name,
T converter(pmt::pmt_t),
boost::function<void(typename NonDeduced<T>::type)> action)
// T deducible from action
template<typename T>
void
register_msg_action(const pmt::pmt_t& name,
boost::function<typename NonDeduced<T>::type (pmt::pmt_t)> converter,
void action(T))
// T deducible from both, must match
template<typename T>
void
register_msg_action(const pmt::pmt_t& name,
T converter(pmt::pmt_t),
void action(T))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.