2013-07-28 16 views
5

ile init almıyor, çalışıyorunique_ptr varsayılan deleter

std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr; 
ptr = std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)>(new Animal<Cat>, [](Animal<Cat> *ls) { 
    delete ls; 
}); 

hatası:

Bu

/usr/bin/../lib/c++/v1/memory:2561:13: error: static_assert failed "unique_ptr constructed with null function pointer deleter" 
       static_assert(!is_pointer<deleter_type>::value, 
       ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
note: in instantiation of member function 'std::__1::unique_ptr<Animal<Cat>, void (*)(Animal<Cat> *)>::unique_ptr' requested here 
      std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr; 
                   ^
benim derleyici sürümü:

Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn) 
Target: x86_64-apple-darwin12.4.0 
Thread model: posix 

Hayvan ve kedi sınıfları önemsiz. This is the entire code.

cevap

10

Bu görünüşte mümkün olmayan bir deleter için bir işaretçi türü ile unique_ptr varsayılan-yapı.

unique_ptr<int, void(*)(int*)> ptr{nullptr,[](int*p){delete p;}}; 
// ... 
ptr.reset(new int(42)); 
: o standart uyumdur olduğunu istedikleriyle

constexpr unique_ptr() noexcept;

4 Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D [the deleter type], the program is ill-formed.

şey benzer: unique_ptr kurucular içinde §20.7.1.2.1 [unique.ptr.single.ctor] diğer şeyler arasında, diyor ki ayrıntılı olarak

10

yukarıda Casey cevabı okuduktan sonra çalışması için yerine lambda eski güzel fanktorlar kullanmak için kodumu değiştirdi.

struct Deleter { 
    void operator()(Animal<Cat>* ls) { 
     delete ls; 
    } 
}; 

int main() { 
    std::unique_ptr<Animal<Cat>, Deleter> ptr; 
    ptr = std::unique_ptr<Animal<Cat>, Deleter>(new Animal<Cat>); 
    return 0; 
} 
+1

bu 'unique_ptr' davranış için gerekçe boş işaretçi fonksiyonlu iyi deleter olmadığını derleme zamanında bilgilendirmek için çalışmaktır:

Bu benim çözümdür. Bu davranışı açıkça bir nullptr deleter içine göndererek geçersiz kılabilirsiniz. Ama bunun yerine seçtiğiniz çözüm daha iyi imho. –

+0

@HowardHinnant Çalışma zamanında nullptr'yi kontrol edecek mi yoksa o işlevi çağırmaya çalışacak mı? – user877329

+0

@ user877329: '~ unique_ptr()' veya 'reset()' çağrılırsa ve 'get_deleter() (get())' iyi biçimlendirilmemişse, tanımlanmamış bir davranış alırsınız. –