2017-04-07 118 views
0

我想在C++ 17下的类模板扣除。
我写了一个示例类模板,可以在不指定模板类型的情况下构建。没有指定类型就无法构造std::unique_ptr
我需要帮助理解为什么是这种情况。C++ 17类模板扣除

使用铛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)); 
+1

您是否愿意告诉我们错误信息是什么? –

+1

Meta小贴士:当你想说“请忽略所有细节”时,尝试使用*来处理所有细节,看看问题是否仍然不清楚。很多事情都是关于细节的。 –

+0

@KerrekSB如果它没有编译含义,那么编译器是否抱怨提供模板类型并不那么明显?有什么关心或不关心? – Jagannath

回答

4

类模板std::unique_ptr比你的玩具例子更复杂。其主要所有权回吐构造函数采用形式

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

其中pointer要么D::pointerremove_reference_t<D>::pointerT*。因此,如果您想从构造函数中推导出类模板参数,首先需要知道哪个删除程序提供了指针类型,这会导致循环依赖性,因此您无法知道构造函数参数应为TD。为了避免任何意外的错误解释,标准明确要求这个构造函数不能用于模板参数推导(感谢@ T.C.指出精确的措辞!)。

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

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

+1

LWG增加了特定的措辞,说从'指针'的推导是不合适的,正是由于'T'与'T []'的问题。 –

+0

好,所以如果编译失败,请尝试编译而不提供模板类型,然后提供类型。这就是我所了解的功能的全部内容 – Jagannath

+0

@ T.C .:但是有没有具体的措词来实现这个功能呢,还是只是从现有的类定义中自然地遵循?我没有看到任何明确的指南。 –