2010-08-06 69 views
5

有人請解釋爲什麼我在這裏得到編譯錯誤 - 錯誤C2558:class'std :: auto_ptr < _Ty>':沒有拷貝構造函數可用或拷貝構造函數聲明爲 '顯性'沒有拷貝構造函數可用或拷貝構造函數被聲明爲'explicit'

#include <memory> 
#include <vector> 
#include <string> 
template<typename T> 
struct test 
{ 
    typedef std::auto_ptr<T> dataptr; 
    typedef std::auto_ptr< test<T> > testptr; 
    test(const T& data): 
    data_(new T(data)) 
    { 
    }; 
    void add_other(const T& other) 
    { 
     others_.push_back(testptr(new test(other))); 
    } 
private: 
    dataptr data_; 
    std::vector<testptr> others_; 
}; 

int main(int argc, char* argv[]) 
{ 
    test<std::string> g("d"); 

    //this is the line that causes the error. 
    g.add_other("d"); 

    return 0; 
} 
+0

我已經完成了C++,但不應該是'g = test (「d」);'? – 2010-08-06 00:09:56

+0

@Jesse J:兩個都沒問題。這兩種方式的行爲略有不同,除了最惡劣的情況外,其他行爲都有相同的結果。從技術上講,你的方法將創建一個測試類,然後將其分配給g,而不僅僅是初始化g本身。當你有自定義的複製/分配/初始化行爲時,這隻會成爲一個問題。 – Akusete 2010-08-06 00:32:34

+0

謝謝大家。真正的信息答案。 – Carl 2010-08-06 01:07:19

回答

6

基本上不能以這種方式使用std::auto_ptr

others_.push_back(testptr(new test(other))); 

需要一個拷貝構造函數,一個const&存在,沒有這樣的構造存在std::auto_ptr。這被廣泛視爲好東西因爲你不應該在容器中使用std::auto_ptr如果你不明白爲什麼這是,那麼read this article by Herb Sutter,特別是標題爲「不要做的事情,爲什麼不做它們」約3/4的方式。

+1

如果標準容器被強制使用'swap'來複制東西,auto_ptr會起作用。我真的希望他們是。在C++ 0x中,':: std :: unique_ptr'(非常像':: std :: auto_ptr')也沒有複製構造函數,只有一個移動構造函數,並且標準容器是強制的要使用移動構造函數來移動它們的內容,所以你可以將':: std :: unique_ptr'存儲在它們中並使它按預期工作。 – Omnifarious 2010-08-06 01:39:46

+0

事實上,在容器中使用'auto_ptr'是非法的,因爲STL容器要求它們的成員具有「正常」的複製行爲。 Auto_ptr不符合該要求。 – 2010-08-06 01:39:55

+1

@Omnifarious:您正在將shared_ptr與unique_ptr混合使用。 Shared_ptr是引用計數的智能指針,而不是具有移動語義的指針。 – 2010-08-06 01:40:39

4

不能創建的auto_ptr的標準庫中的容器,因爲你正試圖在這裏做的事:

std::vector<testptr> others_; 

,因爲他們沒有正確的語義。您將不得不使用普通指針或智能指針的不同風格,如shared_ptr