与"运算符="不匹配

no match for ‘operator=’

本文关键字:quot 不匹配 运算符      更新时间:2023-10-16

在下面的示例中,我正在尝试是否尝试通过引用从fun()返回,那么它会像它应该的那样给我警告。

但是,当我尝试按值返回时,我希望"operator=()"被触发,但它会抛出以下错误,我无法弄清楚原因:

error: no match for ‘operator=’ (operand types are ‘Auto_ptr2<Resource>’ and ‘Auto_ptr2<Resource>’)
note: no known conversion for argument 1 from ‘Auto_ptr2<Resource>’ to 
‘Auto_ptr2<Resource>&’

令人惊讶的是,res2=res1很好地调用了"operator=(("!!

template<class T>
class Auto_ptr2
{
T* m_ptr;
public:
Auto_ptr2(T* ptr=nullptr)
:m_ptr(ptr)
{std::cout<<"nAuto_ptr CTOR called ";}
~Auto_ptr2()
{
std::cout<<"n~Auto_ptr2 calledn";
delete m_ptr;
}
// A copy constructor that implements move semantics
Auto_ptr2(Auto_ptr2& 
{
std::cout<<"nAuto_PTR2 copy constructor called";
m_ptr = a.m_ptr; 
a.m_ptr = nullptr; 
}
Auto_ptr2& operator=(Auto_ptr2& a) 
{
std::cout<<"nAuto_ptr2 operator = called";
if (&a == this)
return *this;
delete m_ptr; 
m_ptr = a.m_ptr; 
a.m_ptr = nullptr; 
return *this;
}
T& operator*() const { return *m_ptr; }
T* operator->() const { return m_ptr; }
bool isNull() const { return m_ptr == nullptr;  }
};
class Resource
{
public:
Resource() { std::cout << "nResource acquired"; }
~Resource() { std::cout << "nResource destroyed"; }
};
Auto_ptr2<Resource> fun(Auto_ptr2<Resource> res3)
{
std::cout << "nres1 is " << (res3.isNull() ? "null" : "not null");
return res3;
}
int main()
{
Auto_ptr2<Resource> res1(new Resource);
Auto_ptr2<Resource> res2; 
res2 = res1; // res2 assumes ownership, res1 is set to null
res2=fun(res2); //ERROR : error: no match for ‘operator=’ (operand types are ‘Auto_ptr2<Resource>’ and ‘Auto_ptr2<Resource>’)

return 0;
}

如果我理解正确,您正在编写类似于std::unique_ptr的东西.

所以,至于std::unique_ptroperator=()应该使用移动语义,所以接收一个r-vale引用,Auto_ptr &&,而不是l值引用

Auto_ptr2& operator=(Auto_ptr2 && a) 
{
std::cout<<"nAuto_ptr2 operator = called";
if (&a == this)
return *this;
delete m_ptr; 
m_ptr = a.m_ptr; 
a.m_ptr = nullptr; 
return *this;
}

并且使用应该通过std::move()

res2=fun(std::move(res2));

构造函数的相同问题:避免复制构造函数(可能删除它(并编写移动构造函数。

Auto_ptr2 (Auto_ptr2 const &) = delete;
Auto_ptr2 (Auto_ptr2 && a) 
{
std::cout<<"nAuto_PTR2 move constructor called";
m_ptr = a.m_ptr; 
a.m_ptr = nullptr; 
}