【问题标题】:std::function: Strict compile time verification of argumentsstd::function:参数的严格编译时验证
【发布时间】:2012-01-13 22:24:23
【问题描述】:

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

该类具有模板化 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, 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)演示:

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;
}

这里触发了访问者建议的静态断言,尽管函数签名是有效的:

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"

我认为最好只比较函数参数和返回值。请提出建议。

谢谢。

【问题讨论】:

    标签: c++ templates gcc c++11 std-function


    【解决方案1】:

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

    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

    【讨论】:

    • 太棒了!我试图使用 std::is_same,但我错误地使用了 type_a/type_b 而不是函数签名。顺便说一句,是否可以从 std::function typedef (DRY) 中推断出函数的类型?
    • 这里用处不大,因为 std::function 接受任何类型的函数,只要它们可以使用作为模板参数给出的参数类型调用。 - 至于从type_a 中提取bool(int&amp;),是的,从技术上讲,这可以通过元函数:ideone.com/dU3b7
    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    相关资源
    最近更新 更多