#c #templates
#c #шаблоны
Вопрос:
Давайте рассмотрим выдержку:
void myFunc(int a, int b) {}
template<void(*function_pointer)(int, int)>
class TakeFunctionPointer {
public:
TakeFunctionPointer() {
function_pointer(5, 6);
}
};
int main() {
TakeFunctionPointer<myFunc> tfp{};
}
Этот код скомпилирован отлично, и он работает, но меня беспокоит, почему компилятор позволяет помещать указатели на функции в параметры шаблона, потому что, как я знаю, шаблоны в C являются частью статического полиморфизма, и ожидается, что сначала компилятор создает экземпляры всех классов шаблонов, а затем запускает их. Итак, это означает, что компилятор может принимать адрес функции с заданной сигнатурой и фактически помещает адрес. Это позволяет классу вызывать удобную функцию.
Как так получилось?
Комментарии:
1. Почему это не должно быть возможно?
2. Если это не достаточно странно, вы также можете иметь указатели на глобальные переменные в качестве параметров шаблона.
3. @Justin Скорее я имел в виду, что меня интересует, на каком шаге компилятор имеет информацию об адресе объекта…
Ответ №1:
Почему компилятор позволяет помещать указатели на функции в параметры шаблона?
Потому что стандарт говорит, что это разрешено.
Итак, это означает, что компилятор может принимать адрес функции с заданной сигнатурой и фактически помещает адрес.
Правильно.
Комментарии:
1. Очень короткий и лаконичный ответ! 🙂
Ответ №2:
Существует разница между class
аргументами шаблона типа и аргументами типа значения. Если у вас есть шаблон, в котором уже задан фактический тип, например
template<std::size_t N> /* class or function... */
вы имеете дело со значением параметра. Это также верно для конкретных указателей на функции, например
template<void(*function_pointer)(int, int)> /* ... */
Вы создаете экземпляр этого шаблона с определенной ссылкой на функцию, которая соответствует сигнатуре, и в определении шаблона вы можете использовать это значение.
Обратите внимание, что использование указателей на функции, подобных этому, т. Е. Во время компиляции, возможно, потому что функции и их сигнатуры должны быть известны во время компиляции в любом случае.