请考虑下面的简单示例,其中函数bar
返回A
具有私有析构函数的类对象,并且必须进行强制返回值优化(RVO):
class A { ~A() = default; };
A bar() { return {}; }
Run Code Online (Sandbox Code Playgroud)
该代码被 Clang 接受,但被 GCC 拒绝并出现错误:
error: 'constexpr A::~A()' is private within this context
2 | A bar() { return {}; }
| ^
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/q6c33absK
哪一个编译器就在这里?
这是这个问题的后续:Does PIMPL idiom 实际上可以使用 std::unique_ptr?
完整的示例使用多个文件,因此为了解决这个问题,我将在这里减少它。完整的工作示例在这里: https: //wandbox.org/permlink/AepAJYkbRU4buDoJ,完整的非工作示例在这里:https://wandbox.org/permlink/0kP23UYJbSaUvJgS。
更短的例子是:
#include <memory>
struct A;
struct B {
~B();
std::unique_ptr<A> p = nullptr;
};
Run Code Online (Sandbox Code Playgroud)
这会产生错误:
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/memory:76:
/opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/bits/unique_ptr.h:83:16: error: invalid application of 'sizeof' to an incomplete type 'A'
static_assert(sizeof(_Tp)>0,
^~~~~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/bits/unique_ptr.h:361:4: note: in instantiation of member function 'std::default_delete<A>::operator()' requested here
get_deleter()(std::move(__ptr));
^
<source>:7:29: note: in instantiation of member function 'std::unique_ptr<A>::~unique_ptr' requested here
std::unique_ptr<A> p = nullptr;
^
<source>:3:8: …
Run Code Online (Sandbox Code Playgroud) c++ pimpl-idiom unique-ptr language-lawyer template-instantiation