The following code is ok:
#include <memory>
#include <vector>
extern template class std::vector<int>;
template class std::vector<int>; // ok on copyable types
int main()
{
[[maybe_unused]] auto v1 = std::vector<int>{}; // ok
[[maybe_unused]] auto v2 = std::vector<std::unique_ptr<int>>{}; // ok
}
However, below is failed to compile:
#include <memory>
#include <vector>
extern template class std::vector<std::unique_ptr<int>>;
template class std::vector<std::unique_ptr<int>>; // error on move-only types
int main()
{
[[maybe_unused]] auto v1 = std::vector<int>{};
[[maybe_unused]] auto v2 = std::vector<std::unique_ptr<int>>{};
}
See: https://godbolt.org/z/8qe94oGx5
Why does extern template instantiation not work on move-only types?
CodePudding user response:
Explicit instantiation definition (aka template class ...
) will instantiate all member functions (that are not templated themselves).
Among other things, it will try to instantiate the copy constructor for the vector (and other functions requiring copyability), and will fail at it for obvious reasons.
It could be prevented with requires
, but std::vector
doesn't use it. Interestingly, Clang ignores requires
in this case, so I reported a bug.