У меня есть класс с перегруженным методом:
#include <iostream>
#include <utility>
struct Overloads {
void foo() {
std::cout << "foo" << std::endl;
}
void foo() const {
std::cout << "const foo" << std::endl;
}
};
Я знаю, что могу работать с указателями на функции-члены (&Overloads::foo).
Поскольку функция здесь перегружена, необходимо поставить static_cast:
int main() {
auto overloads = Overloads{};
auto foo_func = static_cast<void (Overloads::*)()>(&Overloads::foo);
(overloads.*foo_func)(); // foo is printed - as expected
// No idea where to put const and why:
// auto const_foo_func = static_cast<void (Overloads::*) ()>(&Overloads::foo);
//(overloads.*const_foo_func)(); // const foo output is expected
}
Я понимаю, как получить функтор для неконстантного foo. Как я могу получить его для перегрузки const foo?





Вам просто нужно добавить квалификатор const к типу функции в типе указателя функции-члена точно в той же позиции, что и в объявлении функции-члена:
auto const_foo_func = static_cast<void (Overloads::*)() const>(&Overloads::foo);
@ГеоргийГуминов Вы также можете typedef подписи, которые становятся беспорядочными в объявлениях или выражениях. Это то, что я делаю, по крайней мере, для того, чтобы сделать сложный приведение читабельным.
@ГеоргийГуминов Да, синтаксис декларатора/типа C++ поначалу может показаться немного запутанным, но на самом деле он оказывается довольно регулярным. const применяется к тому, что находится слева от него, за исключением случаев, когда оно появляется слева от идентификатора типа или объявления (где оно не является частью декларатора, а является спецификатором decl), поэтому const после * всегда применяется к типу указателя и const после списка параметров ) всегда применяется к типу функции (но только нестатические функции-члены могут фактически иметь тип функции, квалифицированный const).
Ну, я вижу. И
constпослеOverloads::*делает весь типconst. Эта часть работает так же, как простые указатели на функции.