2016-03-06 67 views
0

下面的代碼不會鏗鏘-700.1.81編譯和它的標準庫:是否有效返回指向前向聲明類的unique_ptr?

......./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:

#include <memory> 

class something; 

std::unique_ptr<something> external_function(); 

std::unique_ptr<something> local_function() 
{ 
    auto thing = external_function(); 

    return thing; 
} 

由鐺診斷返回值,但這真的是必要的嗎?它無論如何都會被移動,它是否需要檢查它是否可以在意識到它更容易移動之前進行復制?

我當然可以用裸指針輕鬆做到這一點。 有沒有其他方法可以允許uniqe_ptr只是「穿過」一個翻譯單元,如示例所示,而不包括額外的頭部以獲得類的定義?

------ -------- EDIT另外 與GCC 5.3.0和GNU的libstdC++

試圖不編譯爲好,以類似的錯誤消息。

------ ----編輯

我認爲它只是試圖破壞原有thing對象。 由於魯道夫的缺失者的想法(有點凌亂,但只能選擇這個) 望着庫的代碼,我發現這的unique_ptr代碼:

 if (__tmp) 
       __ptr_.second()(__tmp); 

其中second(_tmp)自毀指向的對象。即使它從未被調用過,編譯器也需要一個定義來編譯它。這很愚蠢,但顯然必須忍受它。

+0

的Gabor,不知你是否可以移動指針出來的功能與std :: move,如果這可能會有所幫助? –

+0

@Thereisnothingwecando'return std :: move(thing)'沒有幫助,'return std :: move(external_function());'也沒有幫助 –

回答

2

cppreference.com

的std ::的unique_ptr可以被構造爲不完全類型T,如方便的使用如在平普爾成語的手柄。如果使用缺省刪除器,則T必須在調用刪除器的代碼中完成,這發生在析構函數中,移動賦值運算符並重置std :: unique_ptr的成員函數。 (相反,std :: shared_ptr不能從原始指針構造爲不完整類型,但可以在T不完整的情況下銷燬)。

因此,利用定製刪除,你可以使用正申報類,如果完全聲明可用於缺失者:

#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; 
} 
+0

Bundilis那你到底在說什麼? –

+0

@Thereisnothingwecando我在說可以訪問類的完整聲明的自定義刪除程序解決了這個問題。 –

+0

謝謝,刪除程序似乎是個不錯的主意,儘管只是爲了滿足庫/編譯器而有點難看。我可以看到爲什麼需要進行移動分配。不過,它爲什麼需要?不是回報應該是移動構造而不是移動分配?什麼是分配給? –