std::function:参数的严格编译时验证

发布于 2024-12-20 03:26:47 字数 2135 浏览 1 评论 0原文

我想实现一个类,它包含两个带有预定义函数签名的回调。

该类具有模板化 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

影子是时光的心 2024-12-27 03:26:47

您可以在构造函数主体中静态断言:

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");

请参阅:http://ideone.com/u0z24

You can statically assert in the constructor body:

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");

See: http://ideone.com/u0z24

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文