我想实现一个类,它包含两个带有预定义函数签名的回调.
该类具有模板化的ctor,它使用std :: bind来创建std :: function成员.我预计如果将具有错误签名的函数传递给ctor,编译器(g 4.6)会抱怨.但是,编译器接受以下内容:
callback c1(i,&test::func_a,&test::func_a);
我能理解为什么会那样做.我试图为static_assert构造一个合适的条件但没有成功.
如何防止出现编译时错误?
#include <functional> using namespace std::placeholders; class callback { public: typedef std::function<bool(const int&)> type_a; typedef std::function<bool(int&)> type_b; template <class O,typename CA,typename CB> callback(O inst,CA ca,CB cb) : m_ca(std::bind(ca,inst,_1)),m_cb(std::bind(cb,_1)) { } private: type_a m_ca; type_b m_cb; }; class test { public: bool func_a(const int& arg) { return true; } bool func_b(int& arg) { arg = 10; return true; } }; int main() { test i; callback c(i,&test::func_b); // Both should fail at compile time callback c1(i,&test::func_a); // callback c2(i,&test::func_b,&test::func_b); return 0; }
更新:来自访客的回答解决了我最初的问题.不幸的是,我有一堆相关的案例需要解决,这些案例通过以下代码(http://ideone.com/P32sU)进行了演示:
class test { public: virtual bool func_a(const int& arg) { return true; } virtual bool func_b(int& arg) { arg = 10; return true; } }; class test_d : public test { public: virtual bool func_b(int& arg) { arg = 20; return true; } }; int main() { test_d i; callback c(i,&test_d::func_a,&test_d::func_b); return 0; }
虽然函数签名有效,但是在这种情况下会触发访问者建议的static_assert:
prog.cpp: In constructor 'callback::callback(O,CA,CB) [with O = test_d,CA = bool (test::*)(const int&),CB = bool (test_d::*)(int&)]': prog.cpp:41:51: instantiated from here prog.cpp:17:12: error: static assertion failed: "First function type incorrect"
我认为最好只比较函数参数和返回值.请建议如何.
谢谢.
解决方法
您可以在构造函数体中静态断言:
static_assert(std::is_same<CA,bool(O::*)(const int&)>::value,"First function type incorrect"); static_assert(std::is_same<CB,bool(O::*)(int&)>::value,"Second function type incorrect");