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.