【发布时间】:2021-03-24 22:35:08
【问题描述】:
以下代码使用 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;
}
我的理解是= 符号导致copy initialization,但是,感谢copy elision,我希望m_ptr2 仍然会被初始化而不会失败。
为什么m_ptr2 需要 ForwardDeclared 的析构函数,而 Clang/GCC 对此是否正确? (奖励:得出 m_ptr1 被 MSVC 错误接受的结论是否正确?)
编辑: 用 clang 记录了一个关于这个问题的错误:https://github.com/llvm/llvm-project/issues/54291
【问题讨论】:
-
请注意,使
ForwardDeclared成为完整类型fixes the compilation problem。 -
@SergeyKalinichenko 但是我知道,这也会增加需要包含的代码量
-
可能是a related bug。
-
@xskxzr 有趣的错误,然而,乍一看它看起来不同。在第一个示例中,它使用客户删除器。此错误也记录在 libstdc++ 中,而 MSVC 和 Clang 使用不同的标准库。 (我强制 libc++ 使用 clang)
-
我重新检查了您的问题(因为我的第一条评论是错误的......),我不认为这是 xskxzr 在这里链接的那种错误 - 我仍然怀疑它根本不是一个错误(发生几乎从来没有当 MSVC 很好时,clang 和 gcc 都是错误的......)。我不完全明白,godbolt如何处理不完整的符号。是否有隐藏设置?您是否在真实项目中重现了这个问题? PS:m_ptr2其实不是直接初始化的吗?
标签: c++ c++17 language-lawyer copy-elision copy-initialization