std::function:参数的严格编译时验证
我想实现一个类,它包含两个带有预定义函数签名的回调。
该类具有模板化 ctor,它使用 std::bind 创建 std::function 成员。我预计如果将带有错误签名的函数传递给构造函数,编译器(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, inst, _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_a, &test::func_b);
// Both should fail at compile time
callback c1(i, &test::func_a, &test::func_a);
// callback c2(i, &test::func_b, &test::func_b);
return 0;
}
更新:访客的回答解决了我最初的问题。不幸的是,我有很多相关的案例需要解决,这些案例通过以下代码进行了演示(http://ideone.com/P32sU< /a>):
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"
我认为最好只是比较函数参数和返回值。请建议如何。
谢谢。
I'd like to implement a class, which holds two callbacks with pre-defined function signatures.
The class has templated ctor, which uses std::bind to create std::function members. I expected that the compiler (g++ 4.6) would complain if a function with wrong signature is passed to the ctor. However, the compiler accepts the following:
callback c1(i, &test::func_a, &test::func_a);
I can understand why it does that. I tried to construct a proper condition for static_assert with no success.
How can I make a compile-time error to prevent this?
#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, inst, _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_a, &test::func_b);
// Both should fail at compile time
callback c1(i, &test::func_a, &test::func_a);
// callback c2(i, &test::func_b, &test::func_b);
return 0;
}
UPDATE: Answer from visitor solves my initial problem. Unfortunatelly I have a bunch of related cases to solve, which are demonstrated with the following code (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 as suggested by visitor is triggered here for this case, although the function signature is valid:
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"
I think it would be best just to compare function arguments and return value. Please suggest how.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以在构造函数主体中静态断言:
请参阅:http://ideone.com/u0z24
You can statically assert in the constructor body:
See: http://ideone.com/u0z24