为什么std :: unique_ptr不允许类型推断?

时间:2016-12-15 11:19:00

标签: c++ c++11 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());

这种约束的原因是什么?

2 个答案:

答案 0 :(得分:26)

这不是std::unique_ptr独有的问题 - 模板类的实例化不会自动从C ++之前的构造函数中推导出类型17 。这就是std::make_uniquestd::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 :(得分:6)

没有演绎指南的真正原因是:

<块引用>

没有从指针类型推导类模板参数because it is impossible to distinguish a pointer obtained from array and non-array forms of new

旁注:另一个答案承诺c++17将允许编译:

事实并非如此。也是因为上述原因。