简体   繁体   中英

C++17 class template deduction

I am trying to under the class template deduction in C++17.
I wrote a sample class template that can be constructed without specifying the template types. std::unique_ptr can't be constructed without specifying the types.
I need help in understanding why that is the case.

Code compiled using 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';

The below code fails to compile.

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

The class template std::unique_ptr is more complicated than your toy example. Its primary ownership-taking constructor takes the form

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

where pointer is either D::pointer or remove_reference_t<D>::pointer or T* . So if you wanted to deduce the class template arguments from the constructor, you would first need to know which deleter provides the pointer type, which leads to a circular dependency, and thus you cannot know what T and D should be from the constructor argument. To avoid any accidental misinterpretation, the Standard explicitly requires this constructor not to be usable in template argument deduction (thanks to @TC for pointing out the precise wording!).

A simple example is that for an argument of type U* you could deduce either unique_ptr<U> or unique_ptr<U[]> ; neither is obviously better, and the wrong choice would be a disaster.

To cut a long story short, the class template arguments of std::unique_ptr are not deducible from constructor arguments, unlike in the case of Sample .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM