2016-12-15 66 views
9

所有的標題。它會更容易讀/寫我的例子中的第二行,因爲模板參數的類型是顯而易見的:爲什麼std :: unique_ptr不允許類型推斷?

#include <memory> 

struct Foo{}; 

int main() 
{ 
    // redundant: good 
    auto foo1 = std::unique_ptr<Foo>(new Foo()); 
    // without explicitness: does not compile 
    auto foo2 = std::unique_ptr(new Foo()); 
} 

當然,如果你想使用多態,我們總是可以寫:

auto base = std::unique_ptr<Base>(new Derived()); 

這種約束的原因是什麼?

+7

使用'std :: make_unique'(C++ 14),所以不要重複。 – Jarod42

回答

21

這並非是一個問題......獨特的std::unique_ptr - 模板類的實例不會自動從以前到C++ 17的構造推斷類型。這就是爲什麼設施如std::make_unique,std::make_pairstd::make_tuple存在:他們使用模板函數參數扣減來減少樣板。


在C++ 17,您將能夠編寫:

auto foo2 = std::unique_ptr(new Foo()); 

感謝class template deduction - 假設P0433R0被接受,還增加了一個扣除指南std::unique_ptr

扣除導是必需的因爲std::unique_ptr's constructor that takes a raw pointer使用其定義如下的pointer類型別名:

std::remove_reference<Deleter>::type::pointer如果該類型存在,否則T*。必須滿足NullablePointer

類型別名像pointer是不可抵扣的上下文,所以P0433R0建議增加的:

template<class T> unique_ptr(T*) 
    -> unique_ptr<T, default_delete<T>>; 

template<class T, class V> unique_ptr(T*, V) 
    -> unique_ptr<T, default_delete<T, V>>; 

template<class U, class V> unique_ptr(U, V) 
    -> unique_ptr<typename pointer_traits<typename V::pointer>::element_type, V>; 

這將使類模板演繹std::unique_ptr

+1

好的答案,但應該指出,儘管'std :: make_unique (...)'減少了樣板,它只能推導出參數的類型到'T''c'tor - 也就是說它只能推導出「ARGS ...」。 – KyleKnoepfel

相關問題