void (* const algorithm)();
а также
void const (* const algorithm)();
когда имеешь дело с const
указатели на статические методы?
Я понимаю, что имеет смысл использовать const
если указатель указывает на память, которая не должна изменяться, в случае указателей на переменные, как указано в этот ответ. Однако, в любом случае, адреса функций не являются постоянными во время выполнения?
Причина, по которой я спрашиваю это второй опция как параметр функции не работает.
РЕДАКТИРОВАТЬ
Вот код, который не компилируется.
struct A {
static void a() {}
};
void b(void const (* const callback)()) {}
int main() {
b(&A::a); // No matching function for call to 'b'
}
Приведенный выше пример работает, если функция a()
имеет тип возврата const void
,
const
после (или до) возвращаемый тип применяется к возвращаемому типу. Не существует такого понятия, как «указатель на константную функцию», поскольку не существует такого понятия, как константная функция. (Хотя существует такая вещь, как указатель на функцию-член const, поскольку функции-члены const существуют. Но здесь константность применяется к аргументу объекта, а не к самой функции. Там константность выражается так же, как в объявление функции-члена — после списка параметров в скобках).
Там нет никакой разницы между void()
а также void const()
в том смысле, что обе функции ведут себя одинаково, потому что нет никакой поведенческой разницы между типом возврата const void и типом неконстантного возврата. Объект не может быть константным, когда его нет.
Я ожидаю, что компилятор выдаст предупреждение, когда возвращаемое значение, не относящееся к классу, напрямую определяется с помощью const.
Тем не мение, void()
а также void const()
отличаются в том смысле, что void
а также void const
являются технически отдельными типами, так как все они являются постоянными квалифицированными типами, отличными от неконстантных. Поэтому указатели на функции с постоянным возвращением и неконстантным возвращением являются разными типами указателей на функции. Таким образом, стандарт не позволяет указателю функции одного типа быть связанным с функцией другого типа.
Итак, чтобы исправить ваш некомпилируемый код, просто замените void const
что бессмысленно с void
в указателе функции.
Начни с «внутреннего» const
:
using void_function = void();
void (*p1)() = nullptr; // similar to `void_function* p1 = nullptr;`
void (* const p2)() = nullptr; // similar to `void_function* const p2 = nullptr;`
p2
является constant
в то время как p1
изменчиво
При переезде const
следующим образом:
const void_function* p3 = nullptr; // or void_function const* p3; // -> const has no effect
void (const* p4)() = nullptr; // Invalid syntax
Нет «const
функция «против» изменяемой функции «.
Теперь посмотрим на тип возвращаемого значения функции:
Типы void ()
(функция, возвращающая void
) а также const void ()
(функция, возвращающая const void
!?) разные.
Даже если const void
не имеет никакого смысла, это допустимый тип.
Возможно, имеет смысл вернуться const
объект из функции, чтобы запретить «прямую» модификацию объекта:
const std::string make_const_string();
make_const_string().push_back('*'); // Doesn't work
std::string s = make_const_string(); // OK, create mutable copy.
Итак, чтобы исправить ваш код:
struct A {
static void a() {}
};
void b(void const (* const callback)()) {}
int main() {
b(&A::a); // No matching function for call to 'b'
}
Вы должны сделать &A::a
матч b
Тип аргумента:
static const void a() {}
void b(void (*const callback)())
Я предлагаю второй как const void
не имеет никакого реального смысла.