[SOLVED] Why does extern template instantiation not work on move-only types?

Issue

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?

Solution

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.

Answered By – HolyBlackCat

Answer Checked By – Mildred Charles (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *