Strange behavior with std::function

c++, c++11, std-function

Solution

Looks like a bug to me. First, here's a simplified example that doesn't play any games with casts:

#include <functional>
#include <iostream>

typedef void (*VF)();

VF Test() {
    return nullptr;
}

int main(int argc, char* argv[]) {
    std::function<void()> foo(Test());
    std::cout << !!foo << std::endl;
    return 0;
}

It still prints 1 with GCC. It shouldn't:

20.8.11.2.1 `template<class F> function(F f);` `template <class F, class A> function(allocator_arg_t, const A& a, F f);` 7 Requires: `F` shall be `CopyConstructible`. `f` shall be `Callable` (20.8.11.2) for argument types `ArgTypes` and return type `R`. The copy constructor and destructor of `A` shall not throw exceptions. 8 Postconditions: `!*this` if any of the following hold:

- `f` is a `NULL` function pointer.

- `f` is a `NULL` pointer to member.

- `F` is an instance of the function class template, and `!f`

Problem

I'm using the standard function wrapper from the C++11 library, and I am seeing some strange behavior with its boolean operator. If I create a `std::function` object the boolean operator returns false. This is still true if I assign `nullptr` to the object and check again. The problem appears when I assign it a void pointer which I have cast into a function pointer. Consider the following program: ``` #include <functional> #include <iostream> void* Test() { return nullptr; } int main(int argc, char* argv[]) { std::function<void()> foo; std::cout << !!foo << std::endl; foo = nullptr; std::cout << !!foo << std::endl; foo = reinterpret_cast<void(*)()>(Test()); std::cout << !!foo << std::endl; return 0; } ``` What I expect as output is `0 0 0` but the result is `0 0 1` (see demo). Can anyone explain why the boolean operator returns true when it contains a null, non-callable function pointer? And please also mention a workaround to check for `nullptr` in `std::function` NOTE: I've already tried checking if the target is null (with `foo.target<void*>() == nullptr`) instead of using the boolean operator, but it seems as if no matter what the function object contains, the target is always null (even when the function object is perfectly fine with being called).

Original source

Related problems