return a unique_ptr 指向前向声明 class 是否有效?
Is it valid to return a unique_ptr pointing to a forward declared class?
以下代码不能用 clang-700.1.81 编译,它是标准库:
#include <memory>
class something;
std::unique_ptr<something> external_function();
std::unique_ptr<something> local_function()
{
auto thing = external_function();
return thing;
}
clang 的诊断:
......./include/c++/v1/memory:2626:46: note: in instantiation of member function 'std::__1::unique_ptr.....requested here
_LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
^
test.cc:10:18: note: in instantiation of member function 'std::__1::unique_ptr<something, std::__1::default_delete<something> >::~unique_ptr' requested here
auto thing = external_function();
^
test.cc:4:7: note: forward declaration of 'something'
class something;
^
我猜它试图在将 unique_ptr 复制为 return 值后销毁它,但这真的有必要吗?反正就是要搬家,是不是先看看能不能复制才知道搬家比较方便?
我当然可以用裸指针轻松做到这一点。
是否有其他方法允许 uniqe_ptr 只 "pass through" 一个翻译单元,如示例所示,而不包括额外的 header 来获得 class 的定义?
------编辑--------
还尝试使用 GCC 5.3.0 和 gnu libstdc++
编译不正常,有类似的错误信息。
------编辑----
我认为它只是想破坏原来的thing
object。
感谢 Rudolf 的删除想法(有点乱,但这是唯一的选择)
查看库代码,我在 unique_ptr 的代码中找到了这个:
if (__tmp)
__ptr_.second()(__tmp);
其中 second(_tmp)
破坏指向的 object。即使它从未被调用,编译器也需要一个定义来编译它。这很愚蠢,但显然必须忍受它。
std::unique_ptr may be constructed for an incomplete type T, such as to facilitate the use as a handle in the Pimpl idiom. If the default deleter is used, T must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of std::unique_ptr. (Conversely, std::shared_ptr can't be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete).
因此,对于自定义删除器,您可以使用前向声明 class 如果完整声明可用于删除器:
#include <memory>
class Foo;
class FooDeleter
{
public:
void operator()(Foo* pInstance);
};
std::unique_ptr<Foo, FooDeleter> pFoo;
class Foo
{
};
void FooDeleter::operator()(Foo* pInstance)
{
delete pInstance;
}
以下代码不能用 clang-700.1.81 编译,它是标准库:
#include <memory>
class something;
std::unique_ptr<something> external_function();
std::unique_ptr<something> local_function()
{
auto thing = external_function();
return thing;
}
clang 的诊断:
......./include/c++/v1/memory:2626:46: note: in instantiation of member function 'std::__1::unique_ptr.....requested here
_LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
^
test.cc:10:18: note: in instantiation of member function 'std::__1::unique_ptr<something, std::__1::default_delete<something> >::~unique_ptr' requested here
auto thing = external_function();
^
test.cc:4:7: note: forward declaration of 'something'
class something;
^
我猜它试图在将 unique_ptr 复制为 return 值后销毁它,但这真的有必要吗?反正就是要搬家,是不是先看看能不能复制才知道搬家比较方便?
我当然可以用裸指针轻松做到这一点。 是否有其他方法允许 uniqe_ptr 只 "pass through" 一个翻译单元,如示例所示,而不包括额外的 header 来获得 class 的定义?
------编辑-------- 还尝试使用 GCC 5.3.0 和 gnu libstdc++
编译不正常,有类似的错误信息。
------编辑----
我认为它只是想破坏原来的thing
object。
感谢 Rudolf 的删除想法(有点乱,但这是唯一的选择)
查看库代码,我在 unique_ptr 的代码中找到了这个:
if (__tmp)
__ptr_.second()(__tmp);
其中 second(_tmp)
破坏指向的 object。即使它从未被调用,编译器也需要一个定义来编译它。这很愚蠢,但显然必须忍受它。
std::unique_ptr may be constructed for an incomplete type T, such as to facilitate the use as a handle in the Pimpl idiom. If the default deleter is used, T must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of std::unique_ptr. (Conversely, std::shared_ptr can't be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete).
因此,对于自定义删除器,您可以使用前向声明 class 如果完整声明可用于删除器:
#include <memory>
class Foo;
class FooDeleter
{
public:
void operator()(Foo* pInstance);
};
std::unique_ptr<Foo, FooDeleter> pFoo;
class Foo
{
};
void FooDeleter::operator()(Foo* pInstance)
{
delete pInstance;
}