Reputation: 3258
How can I write a function that would be compatible either with vanilla pointer types (T*
) or the special pointer types defined in <memory>
such as std::unique_ptr
?
I tried using the std::is_pointer
check, but it looks like this is not the correct approach:
#include <iostream>
#include <memory>
template<typename T>
void SomePointerFunction(
T p, typename std::enable_if<std::is_pointer<T>::value>::type* = nullptr) {
std::cout << (p ? "not null" : "null") << std::endl;
}
int main() {
int* p;
std::unique_ptr<int> q;
SomePointerFunction(p); // If we cange p to q, template matching fails
return 0;
}
Is there some sort of general pointer type defined in C++ that could encapsulate these different types of pointers, or a different template check that would achieve this?
After thinking about it more, I also understand why this would actually be an undesirable feature of the language, because the two types of pointers are very different in many ways. However, if you just want to write a function that utilizes the dereferencing property of pointers, it seems reasonable that this could be useful. Is there some way to say "This function takes one argument, for which the operator *
is defined"?
Upvotes: 2
Views: 117
Reputation: 14279
Is there some way to say "This function takes one argument, for which the operator * is defined"?
There is, just try to dereference it. If it doesn't work, SFINAE kicks in:
template<typename T, typename = decltype(*std::declval<T>())>
We're using std::declval
to get a T
, dereference it and try to get the decltype. The end-result is ignored, we only need it to compile, which means T
is dereferencable.
#include <iostream>
#include <memory>
template<typename T, typename = decltype(*std::declval<T>())>
void SomePointerFunction(
T& p) {
std::cout << (p ? "not null" : "null") << std::endl;
}
int main() {
int* p = nullptr;
std::unique_ptr<int> q;
int i = 0;
SomePointerFunction(p);
SomePointerFunction(q);
//SomePointerFunction(i);
/* Above prints:
main.cpp: In function 'int main()':
main.cpp:16:24: error: no matching function for call to 'SomePointerFunction(int&)'
*/
return 0;
}
Upvotes: 5