I'm looking for a solution for the following problem: I have a class in which I want to overload an operator (in this example &
) for all types of pointers and for all types of arrays. Inside the implementation for arrays I need to have access to the arraysize and inside the implementation for pointers I must be able to do something with the dereferenced object.
As pointed out here, the way for the arrays is quite clear:
template<typename T, unsigned int N>
void operator&(T (&arr)[N])
{
cout << "general array operator: " << N << "\r\n";
}
But for the pointers neither of the following works:
// if I use this, the operator gets ambigous for arrays
template<typename T>
inline void operator&(T* p)
{
cout << "general pointer operator: " << (*p) << "\r\n";
}
// this doesn't work because one cannot dereference void*
void operator&(void* p)
{
cout << "general pointer operator\r\n";
(*this) & (*p);
}
Is there any good and clean solution to achieve different behaviour of an operator for arbitrary arrays and arbitrary pointers?
Here is a complete example code:
#include <iostream>
struct Class
{
template<typename T>
void operator&(T* p)
{
std::cout << "general pointer operator" << (*p) << std::endl;
}
template<typename T, unsigned int N>
void operator&(T (&arr)[N])
{
std::cout << "general array operator" << N << std::endl;
}
};
int main()
{
int myarr[5];
int* p = myarr;
Class obj;
obj & myarr; // error: operator is ambigous
obj & p; // works
return 0;
}
I have to admit that I have no idea why your snippet fails to compile properly. Anyway, a good old tag dispatching workaround seems to be working.
class cClass
{
public:
template<class T, size_t N>
void impl(T (&x)[N], std::true_type)
{
cout << "general array operator" << N << '\n';
}
template<typename T>
void impl(T* p, std::false_type)
{
cout << "general pointer operator" << (*p) << '\n';
}
template<typename T>
void operator&(T && x)
{
impl( std::forward<T>(x), std::is_array< typename std::remove_reference<T>::type >() );
}
};
The solution that changes the least code is:
template<typename T>
void operator&(T*const& p)
which gets rid of the ambiguity. I'd go with tag dispatching myself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With