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.