2016-12-15 70 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

相关问题