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

Fre*_*ios 15 c++ unique-ptr c++11

一切都在标题中.读取/写入我的示例的第二行会更容易,因为模板参数的类型很明显:

#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());
}
Run Code Online (Sandbox Code Playgroud)

当然,如果你想使用多态,我们总是写:

auto base = std::unique_ptr<Base>(new Derived());
Run Code Online (Sandbox Code Playgroud)

这种约束的原因是什么?

Vit*_*meo 26

这不是一个独特的问题std::unique_ptr- 模板类的实例化不会自动从C++之前的构造函数中推导出类型17.这就是为什么等设施std::make_unique,std::make_pairstd::make_tuple存在:他们使用的模板函数参数推导,以减少样板.


在C++ 17中,您将能够编写:

auto foo2 = std::unique_ptr(new Foo());
Run Code Online (Sandbox Code Playgroud)

由于类模板演绎 -假设P0433R0被接受,还增加了一个扣引导std::unique_ptr.

推导指南是必需的,因为std::unique_ptr采用原始指针的构造函数使用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>;  
Run Code Online (Sandbox Code Playgroud)

这将使类模板演绎std::unique_ptr.

  • 我认为这个答案已经过时了?推导指南尚未添加,这是有充分理由的。我添加了自己的答案,但也许修改一下这个答案会更好。 (3认同)
  • 很好的答案,但应该指出虽然`std :: make_unique <T,ARGS ...>(...)`确实减少了样板,但它只能推断出`T`的c'tor的参数类型 - 它只能推断出'ARGS ......'. (2认同)
  • 根据`[unique.ptr.single.ctor]中的C++ 17草案n4750,类模板推导是格式错误的:`如果类模板参数推导(16.3.1.8)将选择对应于此构造函数的函数模板那么这个节目就是格格不入 (2认同)

seh*_*ehe 6

没有扣除指南的真正原因是:

没有从指针类型推导类模板参数,因为无法区分从数组和非数组形式的 new 获得的指针

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

这根本不是那么回事。也是因为上面的原因。