用户定义的指针包装器和 nullptr 比较不会调用我提供的运算符
user defined pointer wrapper and nullptr comparison does not call the operator I have provided
我想比较我的 my_ptr
对象是否是 nullptr
。我希望 x == nullptr
调用我提供的以下运算符。
operator==(std::nullptr_t, const my_ptr<V>& r)
但它没有被调用。我没有在输出屏幕上看到“== nullptr called”。而且,如果我取消注释以下行
my_ptr<int> x2{p2}
结果翻转。我在 g++ 和一些在线编译器中检查了这种行为
#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;
}
看到输出
- 与 my_ptr x2{p2}; 评论
pointer constructor called
void param called 0
- 与 my_ptr x2{p2}; 未评论
pointer constructor called
pointer constructor called
void param called 1
您的接线员有两个问题。
template <typename U, typename V>
bool operator==(std::nullptr_t, const my_ptr<V>& r)
{
std::cout<<"\n == nullptr called\n";
return false;
}
它有一个无法从函数参数推导出来的模板参数 U
,因此您不能将它与运算符调用语法一起使用 x == y
。
其次,您定义了 operator==(std::nullptr_t,const my_ptr<V>&)
但您调用了 operator==(const my_ptr<V>&,std::nullptr_t)
。在 C++20 之前,您需要显式实现其他顺序,当运算符是对称时也是如此。
你得到预期的输出 operator==
:
template <typename V>
bool operator==(const my_ptr<V>&, std::nullptr_t)
{
std::cout<<"\n == nullptr called\n";
return false;
}
正如 DaveS 所指出的,自 C++20 起,实施 operator(std::nullptr,cosnt my_ptr<V>&)
足以调用 x == nullptr
.
最后但同样重要的是,由于在未初始化时使用 p
和 p1
,您的代码具有未定义的行为。
我想比较我的 my_ptr
对象是否是 nullptr
。我希望 x == nullptr
调用我提供的以下运算符。
operator==(std::nullptr_t, const my_ptr<V>& r)
但它没有被调用。我没有在输出屏幕上看到“== nullptr called”。而且,如果我取消注释以下行
my_ptr<int> x2{p2}
结果翻转。我在 g++ 和一些在线编译器中检查了这种行为
#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;
}
看到输出
- 与 my_ptr x2{p2}; 评论
pointer constructor called
void param called 0
- 与 my_ptr x2{p2}; 未评论
pointer constructor called
pointer constructor called
void param called 1
您的接线员有两个问题。
template <typename U, typename V> bool operator==(std::nullptr_t, const my_ptr<V>& r) { std::cout<<"\n == nullptr called\n"; return false; }
它有一个无法从函数参数推导出来的模板参数 U
,因此您不能将它与运算符调用语法一起使用 x == y
。
其次,您定义了 operator==(std::nullptr_t,const my_ptr<V>&)
但您调用了 operator==(const my_ptr<V>&,std::nullptr_t)
。在 C++20 之前,您需要显式实现其他顺序,当运算符是对称时也是如此。
你得到预期的输出 operator==
:
template <typename V>
bool operator==(const my_ptr<V>&, std::nullptr_t)
{
std::cout<<"\n == nullptr called\n";
return false;
}
正如 DaveS 所指出的,自 C++20 起,实施 operator(std::nullptr,cosnt my_ptr<V>&)
足以调用 x == nullptr
.
最后但同样重要的是,由于在未初始化时使用 p
和 p1
,您的代码具有未定义的行为。