Home > Mobile >  The variable of the "typedef function" is initialized to NULL, and the compilation fails?
The variable of the "typedef function" is initialized to NULL, and the compilation fails?

Time:10-11

The following code, VS2015 on my computer fails to compile, but it can be compiled successfully on other computers!

#include <functional>
using namespace std::tr1;

typedef function<void()> OnRun;

class CTest
{
public:
    CTest()
    {
        //The compilation fails
        //if I comment out the compilation is successful
        pOnRun = NULL; // fail
        //pOnRun = NULL; // OK
    }

    ~CTest() {}

private:
    OnRun pOnRun;
};

The compilation error is as follows:

c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1494): error C2893: Failed to make function template "unknown-type std::invoke(_Callable &&,_Types &&...)" Specialization

CodePudding user response:

The typedef is a red herring. std::function has multiple assignment operators, and none of them takes an int. Nor can it work via a converting constructor followed by copy assignment, as there is no converting constructor from int either. There's an assignment operator that takes nullptr, though.

NULL is an old-style C macro, and like all macro's suffers from type problems like this.

CodePudding user response:

From certain versions of VS's stddef.h

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

(I have many questions. To Microsoft developers why they had idea that C can do with just an int. And why there is C branch while their compiler doesn't support C environment at that point. There is some other headers which define NULL and in that case bug might not appear, depending on inclusion order.)

Essentially, this doesn't work because int(0) cannot be implicitly casted to pointer of type void(*)() in this situation during overload resolution:

pOnRun = 0;

It's not recommended to use NULL in C code, NULL is some expression that can be converted to a null pointer but it isn't guaranteed to be a null pointer. C 11 had defined nullptr variable of nullptr_t type convertible to a null pointer of any type to be used portably.

  •  Tags:  
  • c
  • Related