#cpp #шаблоны_с++ #дружественная_функция
templateclass 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 друзьями, добавив в определение класса templatefriend 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
А Вы уверены, что Вам нужны конкретные специализации в качестве "друзей"? Посмотрите, пожалуйста, пример: #includetemplate 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; }
Комментариев нет:
Отправить комментарий