In function call, why doesn't nullptr match a pointer to a template object?
c++, c++11, function-call, nullptr, template-matching
Solution
From the C++ standard (4.10 Pointer conversions [conv.ptr])
1 A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion.
In your first exemple your two nullptr have already been converted before template argument deduction. So there is no problem you have the same type twice.
In the second one, there is a `std::vector<int>` and a `std::nullptr_t` and that does not match. You have to do the conversion yourself: `static_cast<std::vector<int>*>(nullptr)`.
Problem
Here is an example of a code that works perfectly: ``` #include<iostream> #include<vector> template< class D, template< class D, class A > class C, class A = std::allocator< D > > void foo( C< D, A > *bar, C< D, A > *bas ) { std::cout << "Ok!" << std::endl; } int main( ) { std::vector< int > *sample1 = nullptr; std::vector< int > *sample2 = nullptr; foo( sample1, sample2 ); return( 0 ); } ``` In the code below, however, the compiler is unable to match std::vector< int >* with nullptr for the second parameter, even being able to deduct the template types from the first parameter. ``` #include<iostream> #include<vector> template< class D, template< class D, class A > class C, class A = std::allocator< D > > void foo( C< D, A > *bar, C< D, A > *bas ) { std::cout << "Ok!" << std::endl; } int main( ) { std::vector< int > *sample = nullptr; foo( sample, nullptr ); return( 0 ); } ``` The error message is: ``` $ g++ -std=c++11 nullptr.cpp -o nullptr nullptr.cpp: In function ‘int main()’: nullptr.cpp:11:24: error: no matching function for call to ‘foo(std::vector<int>*&, std::nullptr_t)’ foo( sample, nullptr ); nullptr.cpp:11:24: note: candidate is: nullptr.cpp:5:6: note: template<class D, template<class D, class A> class C, class A> void foo(C<D, A>*, C<D, A>*) void foo( C< D, A > *bar, C< D, A > *bas ) { nullptr.cpp:5:6: note: template argument deduction/substitution failed: nullptr.cpp:11:24: note: mismatched types ‘C<D, A>*’ and ‘std::nullptr_t’ foo( sample, nullptr ); ``` Why does that happen?