0

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

pesala
  • 21
  • 4
  • 1
    "*it catch through an exception and getting freeze the functionality*" - not sure I understand what you are trying to say. But, it would be useful if you would provide a [mcve] that works with boost but not with std. – Remy Lebeau Nov 23 '22 at 05:56
  • Please show the problem you're having in code. – sehe Nov 23 '22 at 05:56
  • As far as I know comparing any function<> with a static void method is not possible anyways (https://stackoverflow.com/q/7244881/85371) – sehe Nov 23 '22 at 05:58
  • @sehe I have edited and included the code snippets. – pesala Nov 23 '22 at 07:12

1 Answers1

1

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

sehe
  • 374,641
  • 47
  • 450
  • 633
  • As a sidenote, it looks like you use `function<>` to implement a state machine, it could be wise to make that explicit and not expose the implementation detail. – sehe Nov 23 '22 at 23:48