65
void func(const std::function<void()>& f = empty)
{
    if(f)
        f();
}

what is the 'empty' should be? I use [](){} . But technically, that is not empty, the f() will execute.

jean
  • 2,825
  • 2
  • 35
  • 72

4 Answers4

76
void func(const std::function<void()>& f = {}) {
    if(f) f();
}

LIVE DEMO

101010
  • 41,839
  • 11
  • 94
  • 168
  • @suzuiyue What do you mean? – 101010 Aug 17 '17 at 13:38
  • I do not see bool cast or ! operator overload in [doc](http://en.cppreference.com/w/cpp/utility/functional/function). So why if(f) or if (!f) works? – suzuiyue Aug 18 '17 at 03:01
  • @suzuiyue I am just getting into std::funtion now, but I would assume it's because it was created as a C++ alternative to C-style function pointers, where you check whether or not the fp is null, and f would be a function pointer to the unnamed function created by the lambda. Someone can correct me here if I'm wrong. – Sir Rogers Nov 30 '17 at 11:24
  • 4
    @suzuiyue http://en.cppreference.com/w/cpp/utility/functional/function/operator_bool – 101010 Nov 30 '17 at 11:33
22
const std::function<void()>& f = nullptr

or

const std::function<void()>& f = std::function<void()>()
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
nh_
  • 2,211
  • 14
  • 24
  • 2
    Yes, and the default `std::function` is throwing some exception (I forgot which one).... – Basile Starynkevitch Nov 20 '15 at 08:44
  • @BasileStarynkevitch but OP's code checks the function to see if it's empty before calling. Or is that not what you meant? – TartanLlama Nov 20 '15 at 08:45
  • 2
    @BasileStarynkevitch:- Looking for this one: `1/ An exception of type bad_function_call is thrown by function::operator() (20.8.11.2.4) when the function wrapper object has no target.` ? – Rahul Tripathi Nov 20 '15 at 08:45
  • [nullptr reference is not valid](https://stackoverflow.com/a/4364586/5393174) – kgbook Aug 29 '20 at 07:11
  • 1
    @kgbook not sure that it's what you meant, but `const std::function& f = nullptr` is totally valid. `function& operator=( std::nullptr_t ) noexcept` is defined and drops the current target, making the function empty. – Adrian B. Apr 21 '22 at 16:58
10

I would use a nullptr for the empty case. It can be used because you never use full function objects but only pointers to them, so func(f1); will be in fact func(&f1) => you will always pass pointers to func, so nullptr is IMHO the best candidate.

This compiles and run:

void func(const std::function<void()>& f = nullptr)
{
    if(f)
        f();
}

The alternative of using a default function would be:

void func(const std::function<void()>& f = std::function<void()>()) {
    try {
        f();
    }
    catch(std::bad_function_call e) {
    }
}

using exception catching. The choice between the 2 mainly depends on whether you expect the empty case to occur; almost never: go with exception vs. sometimes: test before call.

As question mentions if (f), use nullptr

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
3

You can try like this:

const std::function<void()> & f = std::function<void()>()

As Basile added, the standard says:

§ 20.8.11.1 Class bad_function_call [func.wrap.badcall]

1/ An exception of type bad_function_call is thrown by function::operator() (20.8.11.2.4) when the function wrapper object has no target.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331