19

I'm updating some of our old code to use C++11 features in place of boost equivalents. However not everything is a simple namespace replacement like unordered containers and smart pointers.

For example boost::function has methods empty() and clear() but std::function does not.

There is an operator() defined for std::function that I've been using to replace empty() references but what should I use to replace clear() references?

I've considered using the std::function assignment operator and assigning nullptr to clear it but I'm worried that might have unintentional side affects of clearing not only the underlying function but rendering the object unusable.

Obviously, the better solution would be default initialization of any reusable member function objects that way there is always a valid callback which can simply be updated with a user provided one but I'm just aiming for a direct replacement of the previous usage right now not a code review.

AJG85
  • 15,849
  • 13
  • 42
  • 50

1 Answers1

27

There is an operator() defined for std::function that I've been using to replace empty()

Do you mean an operator! ?

For empty use that operator to test it in a boolean context:

if (f.empty())

becomes:

if (!f)

Or

if (!f.empty())

becomes:

if (f)

(That also works with boost::function, which also has operator! and operator bool.)

For clear assign nullptr to it, which doesn't render it unusable, it just sets it to a default-constructed state:

f.clear();

becomes

f = nullptr;

Or (thanks to Paul Groke for the suggestion):

f = {};

That's equivalent to:

f = decltype(f){};

but is more efficient, and much easier to type and easier to read!

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Yes, that's what I meant. I worded it that way because the code is riddled with `if (!m_func.empty())` checks which I've been changing to `if (m_func)` ... – AJG85 Jun 22 '12 at 18:17
  • 2
    `f = {};` also works for resetting and I find it to be very elegant. Not sure though if it incurs a runtime overhead compared to `f = nullptr;`. – Paul Groke Jun 25 '18 at 14:36
  • @PaulGroke, yes, that's elegant, and compiles to exactly the same as `f = nullptr`. – Jonathan Wakely Jun 25 '18 at 14:55
  • @JonathanWakely: Looking at boost::function::clear() (https://www.boost.org/doc/libs/1_68_0/boost/function/function_template.hpp) it does more than setting to nullptr, it also possible does a `get_vtable()->clear()`. So is `f = nullptr` really equivalent? – jpo38 Mar 20 '19 at 09:56
  • @jpo38 but how is that different to `std::function::operator=(nullptr_t)`? What do you think that function does? – Jonathan Wakely Mar 20 '19 at 23:31
  • @JonathanWakely: It's hard to say, as there is no more `get_vtable` function in std::function. Maybe it's equivalent, I was just asking. – jpo38 Mar 21 '19 at 07:51
  • @jpo38 it's equivalent. It "does more than setting to nullptr" as you put it. It does the same thing as `clear()`. That's why it's the answer ;-) – Jonathan Wakely Mar 21 '19 at 09:01