std ::вектор указателей на функции: разные параметры шаблона

#c #stl #function-pointers

#c #stl #функции-указатели

Вопрос:

Почему компилируется следующее

 std::vector<int(*)(double)> func_ptrs;
  

но это не

 std::vector<int(double)> func_ptrs
  

?

Во втором случае я получаю одно из этих уродливых сообщений об ошибках STL, поэтому я не собираюсь приводить здесь все, но в конце сообщения я получаю это

 /usr/include/c  /4.8/bits/stl_construct.h:102:30: error: ISO C   forbids incrementing a pointer of type ‘int (*)(double)’ [-fpermissive]
for (; __first != __last;   __first)
  

Это, по-видимому, подразумевает, что C приводит тип int(double) к int (*) (double) . У меня сложилось впечатление, что int(*)(double) и int(double) в любом случае эквивалентны? Или я ошибаюсь?

Хотелось бы получить некоторые разъяснения. Заранее спасибо.

Ответ №1:

int(double) на самом деле это тип функции, а не указатель на функцию. Во многих случаях он распадается на указатель на функцию, но не здесь. Например, вы не можете использовать sizeof с типом функции — и это жизненно важно для vector распределителя.

Что касается вашей конкретной ошибки: add_pointer_t<int(double)> (более или менее это используется vector итератором, внутренне или напрямую) является int(*)(double) и не может быть увеличено, потому что нет смысла выполнять такую операцию.

Комментарии:

1. … и это потому, что размер типа функции зависит от деталей реализуемой функции, и поэтому вы не можете знать ее размер? (или, скорее, он не имеет предсказуемого sizeof значения)

2. Довольно много. Также потребуется экземпляр функции, поскольку сам тип не будет содержать достаточно информации.

3. Вы говорите, что в этом случае он не превращается в указатель на функцию, но почему сообщение об ошибке ссылается на тот факт, что C может не увеличивать указатель на функцию? Откуда взялся этот указатель, на который он ссылается?

4. Из итератора. Скажем, если у вас есть vector<int> , он обрабатывает int* s в итераторах (он может отображать другой тип в качестве итератора, но, в конце концов, это то, что it делает)

5. А, понятно. Большое спасибо. Вы заслуживаете принятия вашего ответа сейчас, даже если он единственный 🙂