unique_ptr和make_unique模板参数自动推导



如果我直接调用类构造函数,为什么我得到自动模板参数推导,但我在std::unique_ptrstd::make_unique中没有得到它?下面是一个示例:

#include <memory>
template <class T>
class C
{
public:
C(const T * const t_) : t(t_) {}
~C(void) { delete t; }
private:
const T * const t;
};

示例 1(工作):

int main(void)
{
const int * const t = new int;
auto * const c = new C(t);
return 0;
}

示例 2(不编译):

int main(void)
{
const int * const t = new int;
auto * const c = new C(t);
std::unique_ptr p(c); // class template argument deduction failed
return 0;
}

示例 3(工作):

int main(void)
{
const int * const t = new int;
const auto c = std::make_unique<C<int>>(t);
return 0;
}

示例 4(不编译):

int main(void)
{
const int * const t = new int;
// no matching function for call to ‘make_unique<template<class T> class C>(const int* const&)
const auto c = std::make_unique<C>(t);
return 0;
}

代码是用g++ -std=c++17(gcc-11.2.0)编译的。

示例 2 和 4 中的问题是什么?如何修复它们?

非常感谢您的帮助!

在 #2 中,CTAD 被故意禁用std::unique_ptr以避免std::unique_ptr(new T[10])的问题,它看起来就像std::unique_ptr(new T),但需要delete[]而不是delete

在#4中,该语言根本不支持这一点:没有办法将任何类模板作为模板参数传递,以便基于std::make_unique中的函数参数执行CTAD。 (可以传递具有特定(元)签名的类模板,但这不适用于常规工具。

这是解决它的一种方法:

template <class T>
auto MakeUnique(T t) 
{ return std::unique_ptr<std::remove_reference_t<decltype(*t)>>(t); }
int main(void)
{
const int * const t = new int;
auto * const c = new C(t);
auto p = MakeUnique(c);
return 0;
}

相关内容

  • 没有找到相关文章

最新更新