Is it possible to overload a function that can tell a fixed array from a pointer?
You may use the following:
namespace detail
{
template <typename T> struct helper;
template <typename T> struct helper<T*> { void operator() () const {std::cout << "pointer\n";} };
template <typename T, std::size_t N> struct helper<T[N]> { void operator() ()const {std::cout << "array\n";} };
}
template <typename T>
void f(const T& )
{
detail::helper<T>{}();
}
Live example
This seems to work for me
#include <iostream>
template<typename T>
std::enable_if_t<std::is_pointer<T>::value>
foo(T) { std::cout << "pointer\n"; }
template<typename T, std::size_t sz>
void foo(T(&)[sz]) { std::cout << "array\n"; }
int main()
{
char const* c;
foo(c);
foo("hello");
}
Bonus std::experimental::type_traits
:
using std::experimental::is_pointer_v;
std::enable_if_t<is_pointer_v<T>>
Your comment made me try something even simpler
template<typename T> void foo(T) { std::cout << "pointer\n"; }
template<typename T, unsigned sz> void foo(T(&)[sz]) { std::cout << "array\n"; }
Of course the problem here is that foo
is now callable for any type, depends on how lax you want your parameter checking to be.
One other way is to (ab)use rvalue references
void foo(char const*&) { std::cout << "pointer\n"; }
void foo(char const*&&) { std::cout << "array\n"; }
Obviously it's not foolproof.