Assigning NULL to std::function issue from VS2010/VS2013

Yesterday I tried to migrate a Visual Studio 2010 C++ project to Visual Studio 2013. But it instantly shows a compile error pointing xrefwrap header which wasn’t clear at first.

Here is the output:

4>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap(283): error C2064: term does not evaluate to a function taking 2 arguments
4> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(228) : see reference to function template instantiation…..

Later it turns out the error was caused by C++11 std::function constructor. Please refer to the following STL’s comment on this here:

The problem is constructing std::function from NULL, which is a macro for 0. In C++11, std::function has many constructors, the relevant ones being:

function() noexcept;
function(nullptr_t) noexcept;
template<class F> function(F);

The default constructor and the nullptr_t constructor produce an empty std::function (i.e. one that tests as false).

The templated constructor (from arbitrary function objects) taking F f has the following requirements according to N3376 20.8.11.2.1 [func.wrap.func.con]/7: “F shall be CopyConstructible. f shall be Callable (20.8.11.2) for argument types ArgTypes and return type R.”

NULL/0’s type is int, and there is no special case for F == int. (int is certainly not a callable function object type!) Therefore, std::function cannot be constructed from NULL/0. Construction from nullptr works because that has a unique type that can select a special constructor.

Note that while we still support the std::tr1::meow names for backwards compatibility (we define std::meow, then provide std::tr1::meow with a using-declaration, so you get the same machinery either way), we are now following C++11 and ignoring TR1 whenever they conflict.

The routine I was trying to compile had a line constructs a std::function by specifying ‘NULL‘ and which was compiled successfully from Visual Studio 2010 with following std::function constructor:

#if defined(_NATIVE_NULLPTR_SUPPORTED) \
&& !defined(_DO_NOT_USE_NULLPTR_IN_STL)
function(int)
{ // construct empty function wrapper from null pointer
this->_Reset();
}
#endif /* defined(_NATIVE_NULLPTR_SUPPORTED) etc. */

VS2013 Solution: As STL indicates, NULL param should be changed to nullptr.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s