Правильно ли думать о шаблонах как о не чем ином, как о том, что компилятор выполняет замену текста и пытается скомпилирC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Правильно ли думать о шаблонах как о не чем ином, как о том, что компилятор выполняет замену текста и пытается скомпилир

Сообщение Anonymous »

Я всегда считал шаблоны чем-то загадочным. Я думаю, это потому, что я никогда особо не задумывался о том, что на самом деле с ними делает компилятор. Однако недавно у меня возникла мысль, и я пришел к выводу, что они, вероятно, на самом деле очень просты. Я хочу знать, является ли моя ментальная модель правильным способом рассуждать о них.
Мой вывод таков: когда компилятор видит шаблон, он фактически выполняет замену строки в исходном коде, прежде чем пытаться скомпилировать результат.
Это можно проиллюстрировать примером.

Код: Выделить всё

struct StringableThing1 {
std::string to_string() { return std::string("hello world"); }
};

struct StringableThing2 {
std::string name;
std::string to_string() { return name; }
};

struct NotAStringableThing {
std::vector data;
std::vector to_binary_string() { return data; }
};

template
void do_something(Stringable something) {
std::string some_string = something.to_string();
std::println(some_string);
}

// works
StringableThing1 thing1;
do_something(thing1);

// works
StringableThing2 thing2;
do_something(thing2);

// does not work
NotAStringableThing thing3;
do_something(thing3);
В приведенном выше примере do_something — это функция шаблона. Параметр шаблона — Stringable. Существует неявное требование, налагаемое кодом этой функции. Это требование заключается в том, что следующий код должен компилироваться для любого Stringable, переданного в качестве параметра шаблона.

Код: Выделить всё

Stringable stringable;
std::string tmp = stringable.to_string();
Другими словами, любой Stringable должен иметь функцию to_string, которую можно вызвать. Эта функция не принимает аргументов и возвращает std::string.
Пример можно расширить и, возможно, сделать более понятным, введя еще одну функцию, которая не компилируется ни для одной из трех структур примера.

Код: Выделить всё

// note same template parameter name chosen deliberately here -
// not the same `Stringable` as before

template
void do_something(Stringable something) {
std::string some_string = something.to_string();
std::println(some_string);
std::vector some_binary_string = something.to_binary_string();
std::println(binary_string_to_utf8(some_binary_string));
}
В данном случае ни один из трех типов не работает. Первые две строки этой функции будут скомпилированы с первыми двумя структурами, а последние две строки — нет. С другой стороны, последние две строки этой функции будут скомпилированы со структурой NotAStringableThing, а первые две строки — нет.
И это все, что нужно? Если да, то шаблоны кажутся на самом деле очень простыми. Не знаю, почему я решил, что они должны быть намного сложнее.

Подробнее здесь: https://stackoverflow.com/questions/798 ... performing
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»