【问题标题】:C++17 class template deductionC++17类模板推演
【发布时间】:2017-04-07 01:18:08
【问题描述】:

我正在尝试在C++17中的类模板下推演。
我编写了一个示例类模板,无需指定模板类型即可构建。 std::unique_ptr 不能在不指定类型的情况下构造。
我需要帮助来理解为什么会这样。

使用 clang 5.0 编译的代码

// Please don't worry about memory leaks, etc. This is sample code anyways.
template<typename T, typename deleter = std::default_delete<T>>
struct Sample
{
T* x_;
deleter func_;

Sample(T* x = nullptr, deleter func = deleter{})
: x_(x)
, func_(func)
{
}
};

auto sample = Sample(new int(10));
std::cout << *(sample.x_) << '\n';

以下代码编译失败。

auto ptr = std::unique_ptr(new int(10)); 

【问题讨论】:

  • 您是否愿意告诉我们错误信息是什么?
  • 元提示:当你想说“请忽略所有细节”时,尝试处理所有细节,看看问题是否仍然不清楚。很多事情都是关于细节的。
  • @KerrekSB 如果它没有编译意义,那么编译器抱怨提供模板类型不是很明显吗?有什么值得关心或不关心的?

标签: c++ c++17


【解决方案1】:

类模板std::unique_ptr 比您的玩具示例更复杂。它的主要所有权获取构造函数采用以下形式

unique_ptr<T, D>::unique_ptr(pointer p)

其中pointerD::pointerremove_reference_t&lt;D&gt;::pointerT*。所以如果你想从构造函数中推导出类模板参数,你首先需要知道哪个删除器提供了指针类型,这会导致循环依赖,因此你不知道TD应该来自什么构造函数参数。为避免任何意外的误解,标准明确要求此构造函数不能用于模板参数推导(感谢@T.C. 指出准确的措辞!)。

一个简单的例子是,对于U* 类型的参数,您可以推导出unique_ptr&lt;U&gt;unique_ptr&lt;U[]&gt;;显然两者都不是更好,错误的选择将是一场灾难。

长话短说,std::unique_ptr 的类模板参数不能从构造函数参数推导出来,这与 Sample 的情况不同。

【讨论】:

  • LWG 添加了具体的措辞,表示从pointer-take ctors 中推断是不正确的,正是由于TT[] 的问题。
  • ok 所以尝试编译不提供模板类型,如果编译失败,则提供类型。据我了解,这就是该功能的全部意义
  • @T.C.:但是是否有具体的措辞来实现这一点,或者它只是自然地遵循现有的类定义?我没有看到任何明确的指南。
  • 他们把它放在构造函数的规范中,like this
  • @T.C.:是的,谢谢。我想说这仍然可以被认为是“这个类模板更复杂”的一部分,但我会更新帖子以调用这个明确的规定。
猜你喜欢
  • 2017-06-09
  • 2017-12-30
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多