Когда создаются экземпляры специальных функций-членов шаблонного класса?

Когда создаются специальные функции-члены (, конструкторы копирования/перемещения и операторы присваивания копирования/перемещения )шаблонного класса? Как только создается экземпляр самого класса или только когда они нужны?

Это происходит в следующей ситуации:

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в этом примере имеет defaulted, потому что, если я изменю его определение на

pair(const pair& p) : first(p.first), second(p.second) {}

, тогда код также пройдет clang.

8
задан HC4 - reinstate Monica 29 April 2012 в 08:16
поделиться