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.