gpt4 book ai didi

C++ 在使用 operator=() 时使用 copy-ctor - 这究竟是如何工作的?

转载 作者:行者123 更新时间:2023-11-28 02:51:09 25 4
gpt4 key购买 nike

C++ 将 operator=() 赋值转换为构造的规则究竟是什么?例如 Foo foo = bar 实际上会调用 Foo 的构造函数,接受 bar 作为参数(如果它存在)。我用谷歌搜索了它是如何工作的,但似乎找不到任何东西。

我在弄清楚为什么下面的赋值试图采用构造函数而不采用明显正确的构造函数时遇到了问题:HandlePtr( TYPE& resource )。使用实际构造语法的构造工作正常,但不适用于赋值运算符。

代码(显然为简洁起见进行了编辑):

template< typename TYPE >
class HandlePtr {
public:
HandlePtr( void ) = default;
HandlePtr( HandlePtr< TYPE >& other ) = default;
HandlePtr( TYPE& resource ) {} // generally I would make this explicit, but for testing purposes I took it out
~HandlePtr( void ) = default;

public:
HandlePtr<TYPE>& operator=( TYPE& resource ) { return *this; }
HandlePtr<TYPE>& operator=( HandlePtr<TYPE>& other ) { return *this; }
};

int main ( void ) {
int x = 5;
HandlePtr< int > g( x ); // works
HandlePtr< int > i;i = x; // works
HandlePtr< int > h = x; // doesn't work

// also tried this just out of curiosity:
HandlePtr< int > h = HandlePtr< int >( x ); // also does not work

return 0;
}

错误:

shit.cpp: In function ‘int main()’:
try.cpp:19:24: error: no matching function for call to ‘HandlePtr<int>::HandlePtr(HandlePtr<int>)’
HandlePtr< int > h = x; // doesn't work
^
try.cpp:19:24: note: candidates are:
try.cpp:7:3: note: HandlePtr<TYPE>::HandlePtr(TYPE&) [with TYPE = int]
HandlePtr( TYPE& resource ) {} // generally I would make this explicit, but for testing purposes I took it out
^
try.cpp:7:3: note: no known conversion for argument 1 from ‘HandlePtr<int>’ to ‘int&’
try.cpp:6:3: note: HandlePtr<TYPE>::HandlePtr(HandlePtr<TYPE>&) [with TYPE = int]
HandlePtr( HandlePtr< TYPE >& other ) = default;
^
try.cpp:6:3: note: no known conversion for argument 1 from ‘HandlePtr<int>’ to ‘HandlePtr<int>&’
try.cpp:5:3: note: HandlePtr<TYPE>::HandlePtr() [with TYPE = int]
HandlePtr( void ) = default;
^
try.cpp:5:3: note: candidate expects 0 arguments, 1 provided
try.cpp:20:20: error: redeclaration of ‘HandlePtr<int> h’
HandlePtr< int > h = HandlePtr< int >( x ); // also does not work
^
try.cpp:19:20: error: ‘HandlePtr<int> h’ previously declared here
HandlePtr< int > h = x; // doesn't work

最佳答案

您在声明中忽略了这一点:

T t = u;

这不是赋值运算符。 t = u; 不是声明的子表达式。这里唯一的表达式是u;表达式 u 的计算结果用作声明对象 t 的初始值设定项。

如果 u 的类型为 T,则 t 是从 u 复制构造的。

如果u没有T类型,那么u首先需要转换为T类型。这将创建 T 类型的右值

您没有任何接受右值的构造函数,因此 T t = u; 和相同的 T t = T(u); 都失败了。但是,T t(u) 成功了,因为没有创建右值;值 u 用作构造函数 T(U &) 的参数。

简化的代码示例:

struct T
{
T(int &);
T(T&);
T();
T &operator=(int &);
};

int main()
{
int x = 5;
T g(x); // OK, T(int &)
T g2(5); // fail, looks for T(int const &)
T i; // OK, T()
i = x; // OK, T::operator=(int&)
T h3 = i; // OK, T(T&)
T h1 = T(x); // fail, looks for T(T const &)
T h2 = x; // fail, identical to previous line
}

通常您应该使用const & 作为复制构造函数和赋值运算符的参数;然后所有这些“失败”情况都变成“OK”,因为右值可以绑定(bind)到 const 引用。

关于C++ 在使用 operator=() 时使用 copy-ctor - 这究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23025259/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com