JVA*_*pen 10 c++ language-lawyer copy-initialization copy-elision c++17
以下代码使用 MSVC (/permissive-) 编译,但无法使用 GCC/Clang 编译 m_ptr1 和 m_ptr2。
#include <memory>
struct ForwardDeclared;
class A {
public:
explicit A();
~A();
private:
std::unique_ptr<ForwardDeclared> m_ptr1 = nullptr; // not ok
std::unique_ptr<ForwardDeclared> m_ptr2 {std::unique_ptr<ForwardDeclared>{}}; // not ok
std::unique_ptr<ForwardDeclared> m_ptr3 {nullptr}; // ok
std::unique_ptr<ForwardDeclared> m_ptr4; // ok
};
int main() {
A a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的理解是该=
符号会导致复制初始化,但是,由于复制省略,我预计m_ptr2
仍会被初始化而不会失败。
为什么m_ptr2
需要 ForwardDeclared 的析构函数并且 Clang/GCC 对此是否正确?(奖励:得出 m_ptr1 被 MSVC 错误接受的结论是否正确?)
我的理解是 = 符号会导致复制初始化,但是,由于复制省略,我预计 m_ptr2 仍会被初始化而不会失败。
复制省略要求类型的析构函数可访问且不可删除,即使没有对象被销毁,请参阅https://en.cppreference.com/w/cpp/language/copy_elision
所以GCC和Clang正确地检查了析构函数,这对于不完整的类型是无效的ForwardDeclared
。
额外奖励:m_ptr1 被 MSVC 错误接受的结论是否正确?
是的,MSVC 这里是不正确的。
请参阅为什么 C++ 中的强制 RVO 需要公共析构函数?了解为什么强制复制省略不适用的解释。
为什么 m_ptr2 需要 ForwardDeclared 的析构函数,Clang/GCC 对此是否正确?
同样的推理也适用于复制省略的有效析构函数的必要性。
归档时间: |
|
查看次数: |
229 次 |
最近记录: |