Функция друга с использованием классов шаблонов С++

Я создал класс, у которого есть функция друга, и когда я объявляю его, проблем нет, но когда я пишу его код, он возвращает мне ошибку:

Нестандартное определение «изменения» не соответствует ни одному объявлению в «MyClass».

Вот код

template <class T>
class MyClass {
private:
    T a;
    
public:
    MyClass(T);
    ~MyClass();
    friend void change(MyClass);
};

template <class T>
MyClass <T> :: MyClass(T value) {
    a = value;
}

template <class T>
MyClass <T> :: ~MyClass() {}

template <class T>
void MyClass <T> :: change(MyClass class) { //Out-of-line definition of 'change' does not match any declaration in 'MyClass <T>'
    a = class.a;
}

person K0sm    schedule 03.12.2020    source источник
comment
Почему вы хотите использовать здесь friend? Какую проблему вы пытаетесь решить? Как вы планируете использовать change?   -  person t.niese    schedule 03.12.2020


Ответы (1)


friend void change(MyClass); не объявляет функцию-член MyClass, это инструкция для компилятора предоставить бесплатную функцию¹ void change(MyClass); доступ к закрытым/защищенным членам MyClass.

Бесплатная функция, которой вы предоставляете доступ к MyClass, должна выглядеть следующим образом:

template <class S>
void change(MyClass<S> obj) {
    obj.a; // obj.a can be accessed by the free function
}

Но тогда friend должен быть объявлен в классе таким образом:

template <class T>
class MyClass {
private:
    T a;
    
public:
    MyClass(T);
    ~MyClass();

    template <class S>
    friend void change(MyClass<S>);
};

Но, основываясь на a = class.a в change, я думаю, что вы действительно хотите это:

template <class T>
class MyClass {
private:
    T a;
    
public:
    MyClass(T);
    ~MyClass();

    void change(MyClass);
};


template <class T>
MyClass <T> :: MyClass(T value) {
    a = value;
}

template <class T>
MyClass <T> :: ~MyClass() {}

template <class T>
void MyClass <T>::change(MyClass class) {
    a = class.a;
}

Функция-член MyClass всегда может получить доступ ко всем членам любого экземпляра MyClass.

1: Что означает термин « бесплатная функция» в C++?

person t.niese    schedule 03.12.2020
comment
К сожалению, объявление друга объявляет не шаблон функции, а конкретную перегрузку. - person molbdnilo; 03.12.2020
comment
@largest_prime_is_463035818 вы можете сделать функцию-член другого класса фаворитом. - person t.niese; 03.12.2020
comment
ну ладно, может я не правильно выразился. Удалил комментарий. - person 463035818_is_not_a_number; 03.12.2020
comment
@largest_prime_is_463035818, но да, я понимаю, что вы имеете в виду. - person t.niese; 03.12.2020
comment
@t.niese Я в этом не сомневался ;) - person 463035818_is_not_a_number; 03.12.2020
comment
Какая бесплатная функция? Ты хочешь сказать, что мне не нужно быть другом? - person K0sm; 03.12.2020
comment
@ K0sm В своем вопросе вы не говорите, почему хотите использовать friend, поэтому трудно сказать. В нынешнем виде я могу только сказать вам, как жареное предназначено для использования. - person t.niese; 03.12.2020
comment
Я хочу иметь доступ к частному члену переданного объекта. - person K0sm; 03.12.2020
comment
@ K0sm свободная функция - это функция, которая не является членом класса, если это недоразумение. В вашем коде friend void change(MyClass); не делает change членом класса, это бесплатная функция - person 463035818_is_not_a_number; 03.12.2020
comment
Спасибо, мой учитель не объяснил это, и мне пришлось искать в Интернете. Теперь я понимаю ошибку. Большое спасибо за ваше время, ребята. - person K0sm; 03.12.2020
comment
@K0smK0sm, если вы хотите изучать С++, я настоятельно рекомендую прочитать хорошую книгу. Я не знаю вашего учителя, но, к сожалению, многие из учителей не знают С++ так хорошо, и вы часто усваиваете дурные привычки и неточные сведения о С++. - person t.niese; 03.12.2020