我怎样才能使boost::函数不那么宽松呢?
How can I make boost::function not be so lenient?
typedef boost::function<void (int,bool)> MyCallback;
void RegisterCallback(MyCallback callback);
class A {
public:
void GoodCallback(int intArg,bool boolArg) {
printf("calling GoodCallback (%d,%s)n",intArg,boolArg?"true":"false");
}
void BadCallback(int intArg) {
printf("calling BadCallback (%d)n",intArg);
}
};
int TestFunction() {
A * myA=new A();
RegisterCallback(boost::bind(&A::GoodCallback,myA,_1,_2));
RegisterCallback(boost::bind(&A::BadCallback,myA,_1));
return 0;
}
是否有任何方法可以使第二次调用RegisterCallback不编译?
背景:
我最近更改了回调签名并添加了bool参数。我以为我已经更新了所有使用这个的东西,但是我错了。除了每次更改签名时重命名RegisterCallback
之外,我希望有一种方法可以让编译器强制使用所有参数。
说明
任何额外的参数都被静默忽略
必须这样才能支持_N
占位符。证人:
void foo (int a, const char* b) {
std::cout << "called foo(" << a << "," << b << ")" << std::endl;
}
int main () {
boost::bind(foo,_1, _2)(1, "abc", foo, main, 2.0);
boost::bind(foo,_2, _5)(3.0, 2, foo, main, "def");
}
打印
called foo(1,abc)
called foo(2,def)
参数列表开头、结尾或中间的任何参数组合都可以忽略。
你需要一个更简单的粘合剂,不支持任何像_N
占位符。Boost似乎没有。
问题不在于boost::function
;问题是boost::bind
返回的函数对象将接受任何作为参数。Bind或多或少是运行时定义的,而不是编译时定义的。因此,boost::bind
对象可以与任何boost::function
一起使用。
[edit]好的,显然boost::function
是也是一个问题。但这并不是唯一的问题。
你可以用std::function<...>
代替。
在VS2010 SP1上不能编译:
#include <functional>
void foo();
void bar(int);
int main()
{
std::function<void ()> f= std::bind(foo);
std::function<void ()> g= std::bind(bar); // does not match signature, does not compile.
return 0;
}
我给出这个答案有点晚了,但由于问题是绑定,您可以稍后在回调注册函数模板化版本的帮助下执行此步骤,另一个用于常规函数指针:
template<typename C>
void RegisterCallback(void (C::* func)(int, bool), C* inst)
{
MyCallback callback(boost::bind(func, inst, _1,_2));
}
void RegisterCallback(void (*func)(int, bool))
{
MyCallback callback(func);
}
A * myA = new A();
RegisterCallback(&A::GoodCallback, myA);
RegisterCallback(&A::BadCallback, myA); // DOES NOT COMPILE
RegisterCallback(GoodCallback);
RegisterCallback(BadCallback); // DOES NOT COMPILE
这在VS2010中如预期的那样工作,但缺点是需要两个而不是一个回调注册函数来正确处理成员函数和非成员函数。
作为另一个选项,您可以查看boost function_types库。它提供了一个parameter_types元函数,用于提取函数指针的参数类型,并将它们作为MPL序列返回。然后,使用位模板魔术就可以验证回调函数的参数,例如:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/equal.hpp>
using namespace boost;
using namespace boost::function_types;
template< typename Function >
void RegisterCallback(Function f)
{
BOOST_MPL_ASSERT((
mpl::equal<
parameter_types< Function >,
parameter_types< void(int,bool) >
>
));
MyCallback callback(f);
}
template<typename Function, typename T>
void RegisterCallback(Function f, T* inst)
{
BOOST_MPL_ASSERT((
mpl::equal<
parameter_types< Function >,
parameter_types< void (T::*)(int,bool) >
>
));
MyCallback callback(boost::bind(f, inst, _1, _2));
}
这在VS2010中也可以正常工作,但是您仍然需要两个函数声明,尽管如果您在结构中定义它们(并使用默认模板参数T),应该可以将它们打包在一个中;
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- boost::bind()类似的东西,但用于函数调用
- 赋值 boost::intrusive_ptr 而不调用构造函数?
- 创建一个函数的 Python 绑定,返回指向带有 boost 的向量的指针
- 在 boost::variant 中类 holden 的复制构造函数存在问题
- 传递 boost::p ython::numpy::ndarray 作为 boost::p ython 函数的(默认或非
- 如何正确取消析构函数中的 Boost deadline_timer(在多线程环境中)?
- 某些 boost::asio 异步函数是否将处理程序连接到操作,以便处理程序被触发一次?
- 我正在将一个 std::string 传递给一个 boost 函数,该函数对该类型进行常量引用,但该值发生了变化
- 如何通过 boost::p ython 重命名构造函数的关键字参数
- 无法将参数传递给 boost::thread 构造函数
- 如何将类成员函数与param绑定为boost::function的右值
- 调用boost v1.58中的函数时出现模板名称使用无效错误
- 为什么Boost Variant使用模板构造函数而不是Boost::beast::websocket::stream的移
- boost::bind函数缓冲区的最大大小
- 如何正确访问结构值并将其传递给函数 - boost::p ython
- std::bind() 错误:无法确定重载函数"boost::asio::io_service::run"的哪个实例
- 为什么在C++函数 boost::algorithm::join_if 中抛出 std::bad_cast 异常
- 错误:使用已删除的函数boost::shared_mutex::shared_互斥
- 传递一个成员函数来创建一个自由函数boost指针