Can we use std::function and std::ref to replace boost::function and boost::ref, respectively?

158 views Asked by At

Currently, I am removing Boost dependencies from a project. I have replaced boost::function and boost::ref with std::function and std::ref, respectively. I was able to build the project, but in case of executing it catch through an exception and getting freeze the functionality.

Further, after replacing boost::function with std::function, it cannot compare std::function<void()> directly with a static void method.

Does anyone have a suggestion on this?

bool NotificationQueue::evoke(boost::function<void()> runner) {
if (runner == &Sentinel::stop) {
    return false;
} 

}

this worked with boost perfect and when I replaced boost with std these changes had been done

bool NotificationQueue::evoke(function<void()> runner) {
if (runner.target<void()>() == &Sentinel::stop) {
    return false;
} 

Also the following error get throws

static void stop() { throw std::logic_error("stop sentinel should not be executed"); }

where I have included this stop method in the following code

_stopFn(&Sentinel::stop)

void NotificationQueue::postStop() {

postNotification(ref(_stopFn));

unique_lock<mutex> lock(_mutex);
if (!_notificationEnabled) {
    _stopped = true;
    _enabledNotifier.notify_all();
}

}

the above ref was previously was in boost::ref

1

There are 1 answers

1
sehe On

Thanks for the snippets. They help pin-point the feature you miss.

The docs at https://en.cppreference.com/w/cpp/utility/functional/function/target include an example of how to use target<> to get the behaviour you want.

Let's implement is_equal for both boost::function and std::function:

template <typename Sig>
static bool is_equal(boost::function<Sig> const& lhs, Sig* rhs) {
    return lhs == rhs;
}

template <typename Sig>
static bool is_equal(std::function<Sig> const& lhs, Sig* rhs) {
    return lhs && lhs.target_type() == typeid(Sig*) && *lhs.template target<Sig*>() == rhs;
}

Now you can execute the same tests with both boost::function and std::function:

using SIG = void(int);
void foo(int) { std::puts("foo"); }
void bar(int) { std::puts("bar"); }

template <template <typename> class Function> void tests() {
    Function<SIG> f;

    assert(!is_equal(f, &foo));
    assert(!is_equal(f, &bar));

    f = foo;
    assert(is_equal(f, &foo));
    assert(!is_equal(f, &bar));

    f = bar;
    assert(!is_equal(f, &foo));
    assert(is_equal(f, &bar));
}

int main()
{
    tests<boost::function>();
    tests<std::function>();
}

See it Live On Coliru

You could generalize a bit so it doesn't assume static functions with the exact same signature: http://coliru.stacked-crooked.com/a/149fe53bc30f1e70