Это ошибка лягушки.Ваш код правильно сформирован, поэтому, какой бы ни была стратегия компилятора, учитывающая правило «как будто», ваш код должен компилироваться.
Явное создание экземпляра шаблона класса только для экземпляров, для которых предоставляется определение [temp.explicit] / 9 :
Явное определение экземпляра, которое именует специализацию шаблона класса, явно создает экземпляр специализации шаблона класса и является явным определением экземпляра только тех членов, которые былиопределяется в момент создания.
Специальная функция-член, по умолчанию установленная в их первом объявлении, определяется только тогда, когда odr-used .Поэтому я предполагаю, что ошибка заключается в том, что Clang ожидает, что в момент явного создания экземпляра конструктор по умолчанию также был создан.
Таким образом, сначала можно обойтись, объявив конструктор перемещения в заголовочном файле, затемчтобы определить его как значение по умолчанию в файле реализации:
unit.hpp :
template<typename T>
struct foo
{
std::vector<T> data;
foo(foo&&)=default;
foo(std::vector<T>&&v) : data(std::move(v)) {}
};
template<T>
foo<T>::foo(foo&&) noexcept;
extern template struct foo<int>;
unit.cpp :
#include <unit.hpp>
template<T>
foo<T>::foo(foo&&) noexcept = default;
template struct foo<int>; //foo(foo&&) has a definition so it is instantiated with the class.
Это приведет к генерации определения конструктора перемещения по умолчанию (см. [dlc.fct.def.default] / 5 ).Недостатком является то, что определение foo(foo&&)
больше не является встроенным.
В качестве альтернативы решение ниже будет работать:
template<typename T>
struct foo
{
std::vector<T> data;
foo(foo&& o)noexcept:data{move(o.data)}{};
foo(std::vector<T>&&v) : data(std::move(v)) {}
};