为什么外部模板实例化不适用于仅移动类型?

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

下面的代码就可以了:

#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   
}

但是下面编译失败:

#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>>{};    
}

参见:https://godbolt.org/z/8qe94oGx5

为什么外部模板实例化不适用于仅移动类型?

显式实例化定义(又名 template class ...)将实例化所有成员函数(它们本身没有模板化)。

除其他外,它会尝试实例化向量的复制构造函数(以及其他需要可复制性的函数),但由于显而易见的原因会失败。

可以用 requires 阻止它,但 std::vector 不使用它。有趣的是,在这种情况下,Clang 会忽略 requires,因此 I reported a bug.