Why doesn't the function template understand NULL but work with nullptr?

I have a function

int f(std::shared_ptr<MyClass> sptr); 

After that, I write the following template to be able to call it (and some other) functions:

 template <typename Func, typename ArgType> auto call(Func func, ArgType arg) -> decltype(func(arg)) { return func(arg); } 

Why am I getting an error in the third line when I try to use this template with NULL?

 auto r0 = f(0); // OK auto r1 = call(f, nullptr); // OK auto r2 = call(f, NULL); // ERROR! WHY?? 1>------ Build started: Project: ConsoleApplication1, Configuration: Debug x64 ------ 1> main.cpp 1>main.cpp(245): error C2893: Failed to specialize function template 'unknown-type call(Func,Arg)' 1> With the following template arguments: 1> 'Func=int (__cdecl *)(std::shared_ptr<MyClass>)' 1> 'Arg=int' ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+6
source share
2 answers

The key is here:

 Arg=int 

NULL should be a null pointer constant, which before C ++ 11 meant that it should be an integer constant with a value of 0. In your implementation, it is of type int and is probably literal 0 .

Thus, the template parameter is output as int , which is not converted to shared_ptr , therefore, an error.

As for the rest:

 auto r0 = f(0); // OK 

Literal 0 can be considered as a null pointer constant and converted to shared_ptr if it is passed directly to the function. Inside call argument is not a literal, but a variable of type int , which cannot be converted.

 auto r1 = call(f, nullptr); // OK 

nullptr has its own type, which can be converted to shared_ptr .

+9
source

Because in C ++, NULL usually defined as 0 , which is an int . Thus, the type of the ArgType template is ArgType as int , and you cannot convert int to std::shared_ptr .

Note that it works, for example. f(0) (and then should work for f(NULL) ), but that is because the compiler knows that 0 in this case is a null pointer. In the call function, the compiler has no idea what the value of the arg variable is, only that it is of type int , which cannot be converted implicitly to a pointer.

+3
source

Source: https://habr.com/ru/post/981606/


All Articles