Почему я не могу назначить указатель на функцию-член перегруженной функции без использования псевдонима типа?

См. пример ниже. Не могу придумать причину, почему это невозможно. Действительно ли я вынужден использовать decl или typedef? Есть ли другие разумные обходные пути?

struct Foo {
    public:
        int get_res() { return 1; }
        int get_res(int i) { return 1; }
};


// Works!
struct Accessor {
    using overload = int(Foo::*)();
    static constexpr overload resGetter = &Foo::get_res;
};

// error: expected unqualified-id before ')' token
struct Accessor {
    static constexpr int(Foo::*)() resGetter = &Foo::get_res;
};

Не заставляйте меня говорить о том, как это странно выглядит, но static constexpr int(Foo::*resGetter)() = &Foo::get_res;

user4581301 22.05.2024 02:22

Синтаксис является остатком C, int(*resGetter)() — это бесплатная версия функции, и скобки, скорее всего, присутствуют, потому что в противном случае в общем случае невозможно отличить int*resGetter() от функции, возвращающей указатель на int, и, скорее всего, никто мог бы придумать, как заставить int() resGetter анализировать, не сломав что-то еще. Какими бы безумными ни выглядели вещи, для безумия всегда была веская причина. Даже если безумие возникло из-за ограничений инструментов и оборудования, доступных в 1970-х годах.

user4581301 22.05.2024 02:58

Очень полезная информация, если вы хотите продолжать копаться в этой кроличьей норе: isocpp.org/wiki/faq/pointers-to-members

user4581301 22.05.2024 02:59

У вас опечатка. Имя resGetter должно идти сразу после * в int(Foo::*)(). См. этот ответ в дураке: Как я могу определить член класса как указатель

user12002570 22.05.2024 05:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
struct Accessor2 {
    static constexpr int(Foo::*resGetter)() = &Foo::get_res;
};

Вот почему вы обычно не пишете указатели на функции-члены таким образом — это выглядит странно, и люди делают ошибки.

Определения типов не генерируют никакого кода — вы можете использовать их столько, сколько хотите, чтобы ваш код был читабельным.

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

fyodor-the-ignorant 22.05.2024 02:42

«псевдонимы в заголовках кажутся культовым грехом» — ссылка обязательна

paddy 22.05.2024 03:30

честно говоря, "псевдонимы в заголовках кажутся грехом карго-культа" звучит как карго-культ

463035818_is_not_an_ai 22.05.2024 08:18

«Никогда не объявляйте псевдонимы пространства имен или объявления удобного использования в области пространства имен в файлах заголовков, только в файлах .cc». И я бы отнес это к категории удобства. Откуда: «abseil.io/tips/…».

fyodor-the-ignorant 22.05.2024 18:08

Все является грехом, если у вас нет веской причины этого не делать.

user4581301 22.05.2024 19:21

Возможно, большинство моих определений типов из заголовков находятся в классах, а не в пространствах имен, но в целом я бы не стал беспокоиться о каких-то правилах, которые кто-то придумал. Если это улучшает API, я делаю все, что работает.

Christian Stieber 22.05.2024 19:25

@fyodor-the-ignorant, в статье, на которую вы ссылаетесь, не упоминаются псевдонимы типов. Речь идет об использовании объявлений для целых пространств имен и псевдонимов пространств имен. Хотя ссылка на руководство Google дает обоснование: «Как и другие объявления, псевдонимы, объявленные в файле заголовка, являются частью общедоступного API этого заголовка...», и если это то, что вы хотите, тогда сделайте это. Рекомендации Google касаются только того, чтобы не делать его частью общедоступного API, если он не должен быть частью общедоступного API. Я не согласен со многими пунктами руководства Google, но здорово, что в них представлены плюсы и минусы, чтобы вы могли принять решение.

463035818_is_not_an_ai 23.05.2024 11:45

@fyodor-the-ignorant, в руководстве Google даже есть положительные примеры, для которых они рекомендуют указывать это в заголовке.

463035818_is_not_an_ai 23.05.2024 11:49

Возвращаясь к этому: да, на самом деле соответствующая часть касалась того, что эти псевдонимы были объявлены как часть общедоступного API (google.github.io/styleguide/cppguide.html#Aliases). В моем случае эти псевдонимы являются исключительно внутренними деталями, и засорять общедоступный API именами, которые не должны использоваться клиентами, — это беспорядок, и на этом этапе у нас остаются только минусы.

fyodor-the-ignorant 19.06.2024 18:21

Другие вопросы по теме