I want to compare if my my_ptr
object is nullptr
or not. I expected x == nullptr
to call the following operator I have provided.
operator==(std::nullptr_t, const my_ptr<V>& r)
but it is not getting called. I don't see " == nullptr called" displayed on my output screen. And also if I uncomment the following line
my_ptr<int> x2{p2}
the result flips. I checked this behaviour in g and some online compilers
#include <iostream>
#include <type_traits>
#include <utility>
template <typename T>
class my_ptr
{
T* t = nullptr;
public:
my_ptr()
{
std::cout<<"\n No arguments constructor called\n";
}
my_ptr(std::nullptr_t)
{
std::cout<<"\n nullptr constructor called\n";
}
my_ptr(T* t_)
: t(t_)
{
std::cout<<"\n pointer constructor called\n";
}
operator const void*() const
{
std::cout<<"\n void param called ";
return t;
}
};
template <typename U, typename V>
bool operator==(const my_ptr<U>& l, const my_ptr<V>& r)
{
std::cout<<"\n == called\n";
return l.get() == r.get();
}
template <typename U, typename V>
bool operator==(std::nullptr_t, const my_ptr<V>& r)
{
std::cout<<"\n == nullptr called\n";
return false;
}
int main()
{
int *p;
my_ptr<int> x{p};
int *p2;
my_ptr<int> x2{p2}; //uncommenting this line changes the result value
std::cout<<"\n "<<int(x == nullptr)<<"\n";
return 0;
}
Output seen
- with my_ptr x2{p2}; commented
pointer constructor called
void param called 0
- with my_ptr x2{p2}; un-commented
pointer constructor called
pointer constructor called
void param called 1
CodePudding user response:
There are two issues with your operator.
template <typename U, typename V> bool operator==(std::nullptr_t, const my_ptr<V>& r) { std::cout<<"\n == nullptr called\n"; return false; }
It has a template argument U
that cannot be deduced from the function parameters, hence you cannot use it with operator call syntax x == y
.
Second, you defined operator==(std::nullptr_t,const my_ptr<V>&)
but you call operator==(const my_ptr<V>&,std::nullptr_t)
. Before C 20 you need to explicitly implement the other order, also when the operator is symmetric.
You get expected output with this operator==
:
template <typename V>
bool operator==(const my_ptr<V>&, std::nullptr_t)
{
std::cout<<"\n == nullptr called\n";
return false;
}
As pointed out by DaveS, since C 20, implementing operator(std::nullptr,cosnt my_ptr<V>&)
is sufficient to call x == nullptr
.
Last but not least, your code has undefined behavior due to using p
and p1
when they are uninitialized.