gcc:无效错误 "use of deleted function"(复制构造函数)?
gcc: invalid error "use of deleted function" (copy constructor)?
简化问题:
#include <stdio.h>
class X
{
public:
int a = 0;
X() { printf("constr-def %d\n", a); }
X(int i):a(i+1) { printf("constr-i %d\n", a); }
int operator=(int i) { a = i; return i; }
operator bool() { return !!a; }
//~ X(const X& o) { a = o.a; printf("copy-constr %d\n", a); };
//~ const X& operator=(const X& o) { a = o.a; printf("copy-op %d\n", a); return *this; };
X(const X& o) = delete;
const X& operator=(const X& o) = delete;
};
int main() {
X x;
X y = 5; // should be equivalent to X y(5)
printf("results: %d %d\n", x.a, y.a);
}
使用 MSVC 编译时的输出;或者 gcc / MSVC 和未删除的复制构造函数变体处于活动状态(上面已注释掉):
>g++ -Os dede.cpp -o dede
>dede
constr-def 0
constr-i 6
results: 0 6
>Exit code: 0
--> 从不使用复制构造函数; MSVC 按原样成功编译。
使用 gcc 按原样编译(v9.3.0 当前 mingw/msys64 构建):
>g++ -Os dede.cpp -o dede
dede.cpp: In function 'int main()':
dede.cpp:20:8: error: use of deleted function 'X::X(const X&)'
20 | X y = 5; // should be equivalent to X y(5)
| ^
dede.cpp:14:5: note: declared here
14 | X(const X& o) = delete;
| ^
dede.cpp:7:2: note: after user-defined conversion: 'X::X(int)'
7 | X(int i):a(i+1) { printf("constr-i %d\n", a); }
| ^
>Exit code: 1
为什么 gcc 使用 use of deleted
复制构造函数出错,而他在未删除的情况下不使用它?
在 C++17 之前,这样的 copy elision 是一种优化,这是允许的,但复制(或移动)构造函数仍然必须存在且可访问。
自 C++17 起,代码工作正常,因为对于强制复制省略,copy/move 构造函数不需要再次存在或可访问。
C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from.
简化问题:
#include <stdio.h>
class X
{
public:
int a = 0;
X() { printf("constr-def %d\n", a); }
X(int i):a(i+1) { printf("constr-i %d\n", a); }
int operator=(int i) { a = i; return i; }
operator bool() { return !!a; }
//~ X(const X& o) { a = o.a; printf("copy-constr %d\n", a); };
//~ const X& operator=(const X& o) { a = o.a; printf("copy-op %d\n", a); return *this; };
X(const X& o) = delete;
const X& operator=(const X& o) = delete;
};
int main() {
X x;
X y = 5; // should be equivalent to X y(5)
printf("results: %d %d\n", x.a, y.a);
}
使用 MSVC 编译时的输出;或者 gcc / MSVC 和未删除的复制构造函数变体处于活动状态(上面已注释掉):
>g++ -Os dede.cpp -o dede
>dede
constr-def 0
constr-i 6
results: 0 6
>Exit code: 0
--> 从不使用复制构造函数; MSVC 按原样成功编译。
使用 gcc 按原样编译(v9.3.0 当前 mingw/msys64 构建):
>g++ -Os dede.cpp -o dede
dede.cpp: In function 'int main()':
dede.cpp:20:8: error: use of deleted function 'X::X(const X&)'
20 | X y = 5; // should be equivalent to X y(5)
| ^
dede.cpp:14:5: note: declared here
14 | X(const X& o) = delete;
| ^
dede.cpp:7:2: note: after user-defined conversion: 'X::X(int)'
7 | X(int i):a(i+1) { printf("constr-i %d\n", a); }
| ^
>Exit code: 1
为什么 gcc 使用 use of deleted
复制构造函数出错,而他在未删除的情况下不使用它?
在 C++17 之前,这样的 copy elision 是一种优化,这是允许的,但复制(或移动)构造函数仍然必须存在且可访问。
自 C++17 起,代码工作正常,因为对于强制复制省略,copy/move 构造函数不需要再次存在或可访问。
C++17 core language specification of prvalues and temporaries is fundamentally different from that of the earlier C++ revisions: there is no longer a temporary to copy/move from.