Why is type checking inside templates stricter?

I read S. Meyers' Effective Modern C ++, and I found something that I cannot completely envelop.

Clause 8 explains why nullptr should be preferred over 0 or NULL . The main argument in favor of nullptr is a safer behavior when resolving overloads. In practice, you avoid unintentionally mixing between pointers and integer types, but that is not the question of my question.

To get to my actual question, consider the code below, based on the example used in the book:

 #include <memory> class MyClass { int a; }; // dummy functions that take pointer types int f1(std::shared_ptr<MyClass> spw){return 1;}; double f2(std::unique_ptr<MyClass> upw){return 1.0;}; bool f3(MyClass* pw){return true;}; // template that calls a function with a pointer argument template<typename FuncType, typename PtrType> auto CallFun(FuncType func, PtrType ptr) -> decltype(func(ptr)) { return func(ptr); } int main() { // passing null ptr in three different ways // they all work fine int this case auto result1 = f1(0); // pass 0 as null ptr to f1 auto result2 = f2(NULL); // pass NULL as null ptr to f2 auto result3 = f3(nullptr); // pass nullptr as null ptr to f3 } // passing null ptr in three different ways through the template // only nullptr works in this case auto result4 = CallFun(f1, 0); // compile error! auto result5 = CallFun(f2, NULL); // compile error! auto result6 = CallFun(f3, nullptr); // OK return 0; } 

The first three direct calls f1 , f2 and f3 are compiled for both 0 , NULL , and nullptr as a null pointer. The next 3 calls made using the CallFun template CallFun are much more legible: you must use nullptr , or no conversion between integer types ( 0 and NULL ) will be accepted. In other words, type checking seems more stringent when it occurs inside a template. Can someone clarify what is happening?

+7
c ++ types overloading c ++ 11 templates
source share
1 answer

CallFun infers the PtrType type for 0 and NULL as int , which are not implicitly converted to a pointer type.

If you want to see what I mean, just try first storing 0 and NULL in the variable auto 'd and calling f1 a f2 from these variables. They will not compile.

0 and NULL themselves are implicitly discarded into the pointer type, because they are the literal values ​​that I assume. There is probably something in the standard, but I think you understand.

+7
source share

All Articles