Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Дружественные методы в шаблонных классах

#cpp #шаблоны_с++ #дружественная_функция


template
class A {
  int a = 0;
public:
  void func(A second) {
    cout << second.a;
  }
};

int main()
{
  A first;
  A second;
  first.func(second);
}



error C2248: A::a: невозможно обратиться к private члену, 
объявленному в классе A



Попробовал сделать метод дружественным: 

template
  class A {
  private:
    int a = 0;
  public:
    friend void A::func(A second);
    void func(A second) {
      cout << second.a;
    }
  };



error C4596: func: недопустимое полное имя в объявлении члена



Собственно, как обратиться к закрытым данным A из A?
Кроме

public:
  int a = 0;

    


Ответы

Ответ 1



В С++ нет способа объявить что-то другом конкретной специализации шаблонного класса, не определяя этой специализации явно (см. ниже). Поэтому в данном случае проще всего просто сделать все специализации класса A друзьями, добавив в определение класса template friend class A; Если же пытаться как-то минимизировать "лишнюю" дружбу, то можно ограничиться template friend void A::func(A); Это, по-видимому, именно то, что вы пытались сделать в вашем коде. В таком случае методы func(A) смогут свободно лазить в любые специализации A. Если же вы хотите, чтобы другом была только A::func(A) и дружила она только с A, то без определения явной специализации не обойтись, что фактически потребует повторного переписывания определения класса template class A { private: int a = 0; public: void func(A); }; template<> class A { private: int a = 0; public: template friend void A::func(A); void func(A second) { cout << second.a; } }; template inline void A::func(A second) { cout << second.a; } Но, я думаю, результат не стоит таких усилий.

Ответ 2



А Вы уверены, что Вам нужны конкретные специализации в качестве "друзей"? Посмотрите, пожалуйста, пример: #include template class node { public: explicit node(T _value) : m_value(_value) {} public: template void add_child(node& _node) { // логика, не относящаяся к примеру std::clog << "добавлена дочерняя нода [value=" << _node.m_value << "]\n"; } protected: T m_value; template friend class node; }; int main() { node node_i { 1 }; node node_l { 2 }; node node_s { 3 }; node_i.add_child(node_l); node_l.add_child(node_s); return 0; }

Комментариев нет:

Отправить комментарий