boost::signals2::signal 输出错误?

boost::signals2::signal gives wrong output?

我是 boost 库的新手,在练习绑定示例时,我编写了以下代码。但是,似乎 'res' 计算正确,但是正确的结果没有传回信号。请帮忙,下面的代码片段有什么问题。 代码已编译并 运行 于 http://cpp.sh/

#include <iostream>
#include<boost/signals2.hpp>

using namespace std;
class MathObject{
public:
    int AddOps(int op1, int op2);
};

int MathObject::AddOps(int op1, int op2){
    int res = op1 + op2;
    cout << "Result of AddOps: " << res << endl;
    return res;
}

int main(void){
    MathObject mObj;
    boost::signals2::signal<int(int)> incrementer;
    incrementer.connect(boost::bind(&MathObject::AddOps, &mObj, 1, _1));
    boost::signals2::signal<int(int)> doubler;
    doubler.connect(boost::bind(&MathObject::AddOps, &mObj, _1, _1));
    cout << "Incrementer of 5" << incrementer(5) << endl;
    cout << "Doubler of 5" << doubler(5) << endl;
}

输出:

Result of AddOps: 6
Incrementer of 51
Result of AddOps: 10
Doubler of 51

如果您查看 boost::signals2documentation,默认情况下它 return 是最后一个信号执行的值 return。但这不是一个简单的值——它被包裹在 boost::optional 中,因为可能没有信号连接到插槽并且 return 没有合理的值。

boost::optional 可转换为 bool,这就是您输出它时发生的情况 - 它输出 1 这意味着它 does 有一个值。相反,如果你说 cout << incrementer(5).get() 你会得到你的预期输出。

调用信号时,它可能有也可能没有连接任何处理程序。因此它可能会或可能不会产生结果。默认行为是 return 最后连接的处理程序的结果,如果有的话;或者 return 表示 "no result" 的值。因此 incrementer(5)doubler(5) 的 return 值不是 int,而是 boost::optional<int>.

这会导致您观察到的输出,因为 boost::optional<int> 可以隐式转换为 bool,然后再转换为 10 的输出.

您需要先检查结果是否存在,然后从 boost::optional<int> 中获取结果,即 returned:

#include <iostream>
#include<boost/signals2.hpp>

using namespace std;
class MathObject{
public:
    int AddOps(int op1, int op2);
};

int MathObject::AddOps(int op1, int op2){
    int res = op1 + op2;
    cout << "Result of AddOps: " << res << endl;
    return res;
}

int main(void){
    MathObject mObj;
    boost::signals2::signal<int(int)> incrementer;
    incrementer.connect(boost::bind(&MathObject::AddOps, &mObj, 1, _1));
    boost::signals2::signal<int(int)> doubler;
    doubler.connect(boost::bind(&MathObject::AddOps, &mObj, _1, _1));
    boost::optional<int> incremented = incrementer(5);
    if (incremented) {
        cout << "Incrementer of 5: " << *incremented << endl;
    }
    boost::optional<int> doubled = doubler(5);
    if (doubled) {
        cout << "Doubler of 5: " << *doubled << endl;
    }
}