Когда создаются специальные функции-члены (, конструкторы копирования/перемещения и операторы присваивания копирования/перемещения )шаблонного класса? Как только создается экземпляр самого класса или только когда они нужны?
Это происходит в следующей ситуации:
template <class T, class U>
struct pair
{
T first;
U second;
pair() : first(), second() {}
pair(const pair&) = default;
};
struct S
{
S() {}
S(const S&) = delete;
S(S&&) = default;
};
int main()
{
pair<int, S> p;
}
Clang отказывается компилировать этот код со следующими ошибками :
test.cpp:9:5: error: the parameter for this explicitly-defaulted copy constructor is const, but a member or base requires it to be
non-const
pair(const pair&) = default;
^
test.cpp:21:18: note: in instantiation of template class 'pair<int, S>' requested here
pair<int, S> p;
^
, предполагающими, что он пытается создать экземпляр конструктора копирования сразу после создания экземпляра класса.
GCC, однако, прекрасно компилирует код, предполагая, что он попытается создать экземпляр конструктора копирования только в том случае, если он действительно нужен.
Какое поведение компилятора является правильным?
(Аналогичное расхождение наблюдается и для операторов присваивания.)
ОБНОВЛЕНИЕ:Это как-то связано с тем фактом, что конструктор копирования pair
в этом примере имеет default
ed, потому что, если я изменю его определение на
pair(const pair& p) : first(p.first), second(p.second) {}
, тогда код также пройдет clang.