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
102
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, Супермодераторы



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

Сейчас этот форум просматривают: Dmitriy40


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

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