Compiler error : Only Copy elision is wanted, but move constructor seems to be required (by compiler)
Compiler error : Only Copy elision is wanted, but move constructor seems to be required (by compiler)
尝试编译此代码会导致 'newer' 编译器(我猜:支持移动构造函数)的编译器错误。类似于 "attempting to call deleted function".
事实证明,在启用 c++17 时使用 gcc 8.1 和 clang 6.0.0 进行编译(认为是由于 "guarenteed copy elision" 特性所致)是没有错误的。然而,很明显,对于 MSVC 19.14(也启用了 c++17),它失败了,即使它应该具有该功能(19.13 中出现)。那么这只是 MSVC 的一个错误,是否允许这样做,还是完全是另一个功能?
#include <string>
#include <iostream>
#include <sstream>
class A : public std::stringstream {
public:
A(std::string str) : str_(str) {
}
//A(A&&);
~A() {
std::cout << str_;
}
std::string str_;
};
A make_A() {
return A("hello");
}
int test(int num) {
A test = make_A();
}
'A' class 是一个简单的 'exploit' 复制省略(或 RVO - Return 值优化),事实上这不会调用自定义析构函数。
令人惊讶的是,在 A 的移动构造函数的声明中注释,使得代码既可以编译又可以 link。所以它可能看起来像编译器首先 'thinks' 它需要这个函数 - 但后来发现复制省略是可能的。
这是预期的行为 - 应该不需要任何调用。
在没有实现的情况下放入声明不再是好的做法。
我也在寻找更好的解决方案。
更新:该代码用于记录器 class,当被调用时,returns 一个临时字符串流,当它被销毁时会记录字符串缓冲区中的任何内容。记录器还有一些内部信息,例如记录位置、严重性等。
gcc 7.3 的确切编译错误:
<source>: In function 'A make_A()':
<source>:21:19: error: use of deleted function 'A::A(const A&)'
return A("hello");
^
<source>:7:7: note: 'A::A(const A&)' is implicitly deleted because the default definition would be ill-formed:
class A : public std::stringstream {
^
<source>:7:7: error: use of deleted function 'std::__cxx11::basic_stringstream<_CharT, _Traits,
_Alloc>::basic_stringstream(const std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>&) [with
_CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
In file included from <source>:4:0:
/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/sstream:734:7: note: declared here
basic_stringstream(const basic_stringstream&) = delete;
^~~~~~~~~~~~~~~~~~
<source>:7:7: error: use of deleted function 'std::basic_ios<_CharT,
_Traits>::basic_ios(const std::basic_ios<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
class A : public std::stringstream {
^
In file included from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ios:44:0,
from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ostream:38,
from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/iostream:39,
from <source>:3:
/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/bits/basic_ios.h:475:7: note: declared here
basic_ios(const basic_ios&) = delete;
^~~~~~~~~
<source>: In function 'int test(int)':
<source>:25:21: error: use of deleted function 'A::A(const A&)'
A test = make_A();
^
Compiler returned: 1
即使使用最新发布的 MSVC 版本(VS17 版本 15.7.6),"Guarenteed copy elision" 的 MSVC 状态似乎仍有问题。
更新:MS 已修复最新 VS17 版本 15.8.1 的问题
尝试编译此代码会导致 'newer' 编译器(我猜:支持移动构造函数)的编译器错误。类似于 "attempting to call deleted function".
事实证明,在启用 c++17 时使用 gcc 8.1 和 clang 6.0.0 进行编译(认为是由于 "guarenteed copy elision" 特性所致)是没有错误的。然而,很明显,对于 MSVC 19.14(也启用了 c++17),它失败了,即使它应该具有该功能(19.13 中出现)。那么这只是 MSVC 的一个错误,是否允许这样做,还是完全是另一个功能?
#include <string>
#include <iostream>
#include <sstream>
class A : public std::stringstream {
public:
A(std::string str) : str_(str) {
}
//A(A&&);
~A() {
std::cout << str_;
}
std::string str_;
};
A make_A() {
return A("hello");
}
int test(int num) {
A test = make_A();
}
'A' class 是一个简单的 'exploit' 复制省略(或 RVO - Return 值优化),事实上这不会调用自定义析构函数。
令人惊讶的是,在 A 的移动构造函数的声明中注释,使得代码既可以编译又可以 link。所以它可能看起来像编译器首先 'thinks' 它需要这个函数 - 但后来发现复制省略是可能的。
这是预期的行为 - 应该不需要任何调用。
在没有实现的情况下放入声明不再是好的做法。 我也在寻找更好的解决方案。
更新:该代码用于记录器 class,当被调用时,returns 一个临时字符串流,当它被销毁时会记录字符串缓冲区中的任何内容。记录器还有一些内部信息,例如记录位置、严重性等。
gcc 7.3 的确切编译错误:
<source>: In function 'A make_A()':
<source>:21:19: error: use of deleted function 'A::A(const A&)'
return A("hello");
^
<source>:7:7: note: 'A::A(const A&)' is implicitly deleted because the default definition would be ill-formed:
class A : public std::stringstream {
^
<source>:7:7: error: use of deleted function 'std::__cxx11::basic_stringstream<_CharT, _Traits,
_Alloc>::basic_stringstream(const std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>&) [with
_CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
In file included from <source>:4:0:
/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/sstream:734:7: note: declared here
basic_stringstream(const basic_stringstream&) = delete;
^~~~~~~~~~~~~~~~~~
<source>:7:7: error: use of deleted function 'std::basic_ios<_CharT,
_Traits>::basic_ios(const std::basic_ios<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
class A : public std::stringstream {
^
In file included from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ios:44:0,
from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ostream:38,
from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/iostream:39,
from <source>:3:
/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/bits/basic_ios.h:475:7: note: declared here
basic_ios(const basic_ios&) = delete;
^~~~~~~~~
<source>: In function 'int test(int)':
<source>:25:21: error: use of deleted function 'A::A(const A&)'
A test = make_A();
^
Compiler returned: 1
即使使用最新发布的 MSVC 版本(VS17 版本 15.7.6),"Guarenteed copy elision" 的 MSVC 状态似乎仍有问题。
更新:MS 已修复最新 VS17 版本 15.8.1 的问题