如何只连接一次升压信号?

时间:2014-08-05 16:45:29

标签: boost

如何在Boost中实现Qt :: UniqueConnection机制?

基本上,我只想将信号连接一次。

1 个答案:

答案 0 :(得分:1)

据我所知,没有这样的东西,但你可以使用自定义组合器轻松模仿它。

1。使用自定义组合器

您可以忽略任何多余的广告位。例如,这个组合器只会忽略第一个插槽之外的任何内容(即第一个添加了at_front而没有组,或者具有最高优先级的组中的第一个,请参阅 Ordering Slot Call Groups ):

template<typename Result>
struct call_first    {
    typedef boost::optional<Result> result_type;

    template<typename It>
        result_type operator()(It first, It last) const {
            if (first != last)       
                return *first;
            return boost::none;
        }
};

现在这是一个测试用例: Live On Coliru

#include <iostream>
#include <boost/optional/optional_io.hpp>

int foo(int i) { std::cout << "(foo)"; return i*2; }
int bar(int i) { std::cout << "(bar)"; return i+2; }

int main()
{
    using namespace boost::signals2;
    signal<int(int), call_first<int> > sig;
    std::cout << sig(42) << "\n"; // should be none ("--")

    sig.connect(foo);
    std::cout << sig(42) << "\n"; // should return 42*2

    sig.connect(bar);

    std::cout << sig(42) << "\n"; // should still return 42*2
}

打印

--
(foo) 84
(foo) 84

2。修复连接管理

通过使用非常简单的帮助器(假设此示例为c ++ 11),您可以轻松避免双重连接信号:

template <typename Sig, typename F> void try_connect(Sig& sig, F&& f) {
    if (!sig.num_slots()) sig.connect(std::forward<F>(f));
}

template <typename Sig, typename F> void re_connect(Sig& sig, F&& f) {
    sig.disconnect_all_slots();
    sig.connect(std::forward<F>(f));
}

相应的测试用例 Live On Coliru

int main()
{
    using namespace boost::signals2;
    signal<int(int)> sig;
    std::cout << sig(42) << "\n"; // should be none ("--")

    try_connect(sig, foo);
    std::cout << sig(42) << "\n"; // should return 42*2

    try_connect(sig, bar);
    std::cout << sig(42) << "\n"; // should still return 42*2

    re_connect(sig, bar);
    std::cout << sig(42) << "\n"; // should return 42+2
}

输出:

--
(foo) 84
(foo) 84
(bar) 44