2010-08-06 30 views
5

Ai đó có thể giải thích tại sao tôi nhận được lỗi biên dịch ở đây - lỗi C2558: class 'std :: auto_ptr < _Ty>': không có hàm tạo bản sao nào bị tuyên bố 'rõ ràng'Không có hàm tạo bản sao nào có sẵn hoặc hàm tạo bản sao được khai báo 'rõ ràng'

#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

Đã lâu rồi kể từ khi tôi đã thực hiện C++, nhưng không nên là 'g = test (" d ");'? –

+0

@ Jesse J: Cả hai đều ổn. Hai cách có hành vi hơi khác nhau mà trong tất cả, nhưng các trường hợp xấu nhất cho kết quả tương tự. Về mặt kỹ thuật, phương thức của bạn sẽ tạo ra một lớp thử nghiệm, sau đó gán nó cho g, thay vì chỉ khởi tạo g chính nó. Điều này chỉ trở thành một vấn đề khi bạn có các hành vi copy/assign/init tùy chỉnh. – Akusete

+0

Cảm ơn tất cả các bạn. Câu trả lời thực sự mang tính thông tin. – Carl

Trả lời

6

Về cơ bản, không thể sử dụng std::auto_ptr theo cách này.

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

Đòi hỏi rằng một constructor sao chép mà phải mất một const& tồn tại và không có constructor như vậy tồn tại cho std::auto_ptr. Điều này được xem rộng rãi là một điều tốt đẹp kể từ bạn không bao giờ nên sử dụng std::auto_ptr trong vùng chứa! Nếu bạn không hiểu tại sao điều này xảy ra, thì read this article by Herb Sutter, đặc biệt là phần có tiêu đề "Những điều không nên làm và tại sao không thực hiện" khoảng 3/4 cách.

+1

Nếu các thùng chứa tiêu chuẩn được ủy nhiệm sử dụng 'swap' để sao chép mọi thứ xung quanh, auto_ptr sẽ hoạt động. Và tôi thực sự muốn họ. Trong C++ 0x, ':: std :: unique_ptr' (giống như' :: std :: auto_ptr') cũng không có một bản sao contructor, và chỉ có một hàm khởi tạo, và các thùng chứa chuẩn được bắt buộc để sử dụng hàm khởi tạo di chuyển để di chuyển nội dung của chúng xung quanh, vì vậy bạn có thể lưu trữ ':: std :: unique_ptr' trong chúng và làm cho nó hoạt động như mong đợi. – Omnifarious

+0

Trên thực tế, việc sử dụng 'auto_ptr' trong vùng chứa là bất hợp pháp vì các vùng chứa STL yêu cầu các thành viên của họ có hành vi sao chép" bình thường ". Auto_ptr không đáp ứng yêu cầu đó. –

+1

@Omnifarious: Bạn đang trộn shared_ptr với unique_ptr. Shared_ptr là một tham chiếu tính con trỏ thông minh, không phải là một với ngữ nghĩa di chuyển. –

4

Bạn không thể tạo container tiêu chuẩn thư viện của auto_ptr, như bạn đang cố gắng làm ở đây:

std::vector<testptr> others_; 

như họ không có ngữ nghĩa chính xác. Bạn sẽ phải sử dụng con trỏ thông thường hoặc một hương vị khác của con trỏ thông minh, chẳng hạn như shared_ptr.

Các vấn đề liên quan