[英]C++ error C2440: 'initializing': cannot convert from 'class name' to 'same class name'
typedef unsigned int uint32_t;
struct Point {
uint32_t x, y;
Point() :x(0), y(0) {}
Point(Point& p) {
x = p.x;
y = p.y;
}
Point operator=(Point& p) {
x = p.x;
y = p.y;
return *this;
}
};
struct Snake {
Point pp;
Point p() { return pp; }
};
int main() {
Snake s;
Point p1;
Point p2 = p1; //ok
Point p3 = s.pp; //ok
Point wtf = s.p(); //error C2440??
}
I tried to compile the code above and get this weird error: 我试图编译上面的代码,并得到这个奇怪的错误:
error C2440: 'initializing': cannot convert from 'Point' to 'Point'
错误C2440:“正在初始化”:无法从“点”转换为“点”
note: Cannot copy construct struct 'Point' due to ambiguous copy constructors or no available copy constructor
注意:由于复制构造函数模棱两可或没有可用的复制构造函数,因此无法复制构造struct'Point'
I figured out 2 ways to make it works: changing 我想出了两种可行的方法:更改
Point p() { return pp; }
into 成
Point& p() { return pp; }
or adding a move constructor to "Point": 或将移动构造函数添加到“ Point”:
Point(Point&& p) {
x = p.x;
y = p.y;
}
I decided to go with the second option. 我决定采用第二种选择。 But I discover an even weirder problem:
但是我发现了一个更奇怪的问题:
I added some "debug code": 我添加了一些“调试代码”:
#include <iostream>
using std::cout;
typedef unsigned int uint32_t;
struct Point {
uint32_t x, y;
Point() :x(0), y(0) {
cout << "\tPoint()\n";
}
Point(Point& p) {
x = p.x;
y = p.y;
cout << "\tPoint(point& p)\n";
}
Point& operator=(Point& p) {
x = p.x;
y = p.y;
cout << "\tPoint& operator=(Point& p)\n";
return *this;
}
Point(Point&& p) {
x = p.x;
y = p.y;
cout << "\tPoint(Point&& p)\n";
}
};
struct Snake {
Point pp;
Point p() { return pp; }
};
int main() {
cout << "Code 0:\n";
Snake s;
cout << "Code 1:\n";
Point p1;
cout << "Code 2:\n";
Point p2 = p1; //ok
cout << "Code 3:\n";
Point p3 = s.pp; //ok
cout << "Code 4:\n";
Point wtf = s.p(); //error C2440??
char c;
std::cin >> c;
}
Which gives me: 这给了我:
Code 0:
Point()
Code 1:
Point()
Code 2:
Point(point& p)
Code 3:
Point(point& p)
Code 4:
Point(point& p)
Which means the move constructor was not called at all. 这意味着根本没有调用move构造函数。
Why does my first code not work? 为什么我的第一个代码不起作用? And why is move constructor not called even though it's the one fixing the problem?
并且为什么即使它是解决问题的一个方法,也未调用move构造函数?
(I use visual studio 2017) (我使用Visual Studio 2017)
A copy constructor and a copy assignment operator take their input parameter by const reference, but yours are both missing the const
. 复制构造函数和复制赋值运算符通过const引用获取输入参数,但是您都缺少
const
。
Also, assignment operators return *this
by reference , but yours is returning by value . 同样,赋值运算符通过引用返回
*this
,但是您的返回值是value 。
Try this: 尝试这个:
struct Point {
uint32_t x, y;
Point() : x(0), y(0) {}
Point(const Point& p) : x(p.x), y(p.y) {}
Point& operator=(const Point& p) {
x = p.x;
y = p.y;
return *this;
}
};
Note, however, that your struct is trivial, so you should let the compiler generate a default copy constructor and default copy assignment operator for you. 但是请注意,您的结构是微不足道的,因此您应该让编译器为您生成默认的副本构造函数和默认的副本赋值运算符。 Its implementations will suffice for your example:
它的实现足以满足您的示例:
struct Point {
uint32_t x = 0;
uint32_t y = 0;
};
Lastly, there is no need to manually define your own uint32_t
type. 最后,无需手动定义自己的
uint32_t
类型。 C++11 has a standard uint32_t
type defined in the <cstdint>
header. C ++ 11在
<cstdint>
标头中定义了标准的uint32_t
类型。
Your move constructor is not used because of copy elision, that is happening when you return from sp()
And the reason you still need move constructor because before c++17
copy elision is optional so you have to have move constructor in case compiler decides not to use copy elision. 您的move构造函数未使用是因为复制省略,当您从
sp()
返回时会发生这种情况,并且仍需要move构造函数的原因是因为在c++17
之前,copy elision是可选的,因此您必须拥有move构造函数以防编译器决定不要使用复制省略。 And VS2017 is c++14
at the moment I think. 我认为目前VS2017是
c++14
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.