2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение12.02.2023, 08:00 
Аватара пользователя


28/10/21
99
XeuTeP_KoLLIu в сообщении #1581202 писал(а):
Дружественные функции.


В С++ у вас есть три способа создать "друга" для шаблонного класса

Способ 1. Нешаблонная функция-друг для шаблонного класса

Используется синтаксис C++
template <typename T>
class C
{
  T a;

  friend void foo(C &c) // или `foo(C<T> &c)` - то же самое
  {
    c.a = 42;
  }
};
 


Каждый раз, когда вы будете инстанцировать шаблон класса C для какого-то аргумента T - C<int>, C<double> и т.д. - компилятор будет автоматически генерировать дружественную функцию foo с соответствующим аргументом - foo(C<int> &), foo(C<double> &) и т.д. Ключевым моментом, на который при этом нужно обратить внимание, является то, что эти дружественные функции сами по себе не являются шаблонными. Каждая такая функция - вполне конкретна и генерируется для уже известного фиксированного типа аргумента.

Такие "странные" сущности, которое сами по себе не являются шаблонами, но при этом автоматически порождаются в процессе инстанцирования других шаблонов, начиная с С++11 называются термином "templated entities" или неформальным термином temploid (темплоид? шаблоид?). В данном случае foo - это не шаблон функции, а шаблоид :O)

Другим важным моментом является то, что такую дружественную функцию невозможно определить за пределами определения шаблона класса. Язык С++ не предоставляет для этого синтаксиса. Наивная попытка это сделать обычно выглядит примерно так

Используется синтаксис C++
template <typename T>
class C
{
  T a;
  friend void foo(C &c);
};

template <typename T>
void foo(C<T> &c)
{
  c.a = 42;
}
 


Однако такая попытка ошибочна. Результирующий код не будет компилироваться (ошибки линковки или ошибки нарушения доступа), ибо шаблон функции, определенный снаружи не имеет никакого отношения к той функции, которая объявлена в качестве friend внутри определения шаблона класса. Многие компиляторы сразу же выдадут вам соответствующее предупреждение на friend-объявление.

Способ 2. Шаблонная функция-друг для шаблонного класса. Перекрестная дружба

В этом вариант мы сделаем foo шаблоном функции и подружим этот шаблон с нашим шаблоном класса

Используется синтаксис C++
template <typename T>
class C
{
  T a;
  template <typename U> friend void foo(C<U> &c);
};

template <typename U>
void foo(C<U> &c)
{
  c.a = 42;
}
 


Вот это уже корректный вариант. В таком варианте шаблон функции foo<> можно определять как внутри определения шаблона класса, так и снаружи - как вам больше нравится. В примере выше он определен снаружи.

Но обратите внимание, что в таком случае все варианты шаблона foo<> дружат со всеми вариантами шаблона C<>. То есть, например, функция foo<int> имеет доступ к внутренностям класса C<double>. В большинстве случаев это не проблема. Но если вас это раздражает, то у вас есть третий вариант.

Способ 3. Шаблонная функция-друг для шаблонного класса. Эксклюзивная дружба

Это наиболее навороченный вариант, который как правило не стоит затраченных усилий, но тем не менее

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
template <typename> class C;
template <typename U> void foo(C<U> &);

template <typename T>
class C
{
  T a;
  friend void foo<>(C<T> &c);
};

template <typename U>
void foo(C<U> &c)
{
  c.a = 42;
}
 


В этом варианте, например, foo<int> имеет доступ только к внутренностям C<int>, но не к внутренностям C<double>. То есть каждый вариант foo<> дружит только со "своим" вариантом C<> (Кстати, в первом варианте дружба тоже является эксклюзивной.)

 Профиль  
                  
 
 Re: Ошибка Unresolved external. c++ builder 10.4
Сообщение12.02.2023, 14:53 


24/01/22
61
Спасибо

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 17 ]  На страницу Пред.  1, 2

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group