Why does the following not compile:
#include <iostream>
#include <cstring>
template <typename U>
void f_broken(std::add_pointer_t<std::remove_pointer_t<U>> p)
{
}
template <typename U>
void f_ok(U p)
{
}
int main() {
int * ptr;
std::cout << typeid(ptr).hash_code() << std::endl;
std::cout << typeid(std::add_pointer_t<std::remove_pointer_t<decltype(ptr)>>).hash_code() << std::endl;
// f_broken(ptr); Compiler error.
f_ok(ptr) // Works.
};
The types are the same as expected but when used it is not behaving as expected.
The compiler error is:
<source>:21:17: error: no matching function for call to 'f_broken(int*&)'
f_broken(ptr);
^
<source>:5:6: note: candidate: 'template<class U> void f_broken(std::add_pointer_t<typename std::remove_pointer<_Tp>::type>)'
void f_broken(std::add_pointer_t<std::remove_pointer_t<U>> p)
^~~~~~~~
<source>:5:6: note: template argument deduction/substitution failed:
<source>:21:17: note: couldn't deduce template parameter 'U'
f_broken(ptr);
Running example: https://godbolt.org/z/UUYHvM