powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Взятие адреса перегруженного метода класса
11 сообщений из 11, страница 1 из 1
Взятие адреса перегруженного метода класса
    #39065908
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В шаблонную функцию нужно передать адрес перегруженного метода некоторого класса:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
struct Foo
{
    void MySignal()   {}
    void MySignal(int)   {}
};

template <typename Signal>
void Connect( Signal signal )
{
}

void Test()
{
    // Не компилируется:
    // Connect( &Foo::Signal );

    // Компилируется, но жутко неудобно:
    Connect( static_cast<void (Foo::*)(int)>(&Foo::MySignal) );

    // Пробуем макросы с переменным числом аргументов. Работает.
    #define signal(a_class, a_method, ...) \
        static_cast<void (a_class::*)(__VA_ARGS__)>(&a_class::a_method)

    Connect( signal(Foo, MySignal, int) );
}



А теперь нужно макрос signal переделать на шаблонную функцию с переменным числом аргументов. Как-то так:

Код: plaintext
1.
2.
3.
4.
5.
6.
template <typename t_class, typename... t_arguments>
    decltype(void (t_class::*)(t_arguments))
        Signal( void (t_class::*ptr)(t_arguments...) )
{
    return static_cast<void (a_class::*)(t_arguments)>(ptr);
}



Это заведомо неверно, но у меня даже идей не возникает как это сделать правильнее. А у вас идеи есть?
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066094
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

Так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
template <typename t_class, typename... t_arguments>
    auto Signal( void (t_class::*ptr)(t_arguments...) )
{
    return static_cast<void (t_class::*)(t_arguments...)>(ptr);
}
void Test()
{
Connect( Signal<Foo, int>(&Foo::MySignal) ); 
}



Можете ещё глянуть в сторону std::result_of
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066123
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZpetrav,

Так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
template <typename t_class, typename... t_arguments>
    auto Signal( void (t_class::*ptr)(t_arguments...) )
{
    return static_cast<void (t_class::*)(t_arguments...)>(ptr);
}
void Test()
{
Connect( Signal<Foo, int>(&Foo::MySignal) ); 
}



Можете ещё глянуть в сторону std::result_of
Увы. Выдаёт "error C3551: expected a trailing return type". Студия 2013.

Если уж типа auto возвращаем, то можно так, наверное:
Код: plaintext
1.
2.
3.
4.
5.
6.
template <typename t_class, typename... t_arguments>
    auto Signal( void (t_class::*ptr)(t_arguments...) ) ->
        decltype( void (t_class::*ptr)(t_arguments...) )
{
    return static_cast<void (t_class::*)(t_arguments...)>(ptr);
}



Но результат как и у меня раньше плачевный: error C2893: Failed to specialize function template 'unknown-type test::Signal(void (__thiscall t_class::* )(t_arguments...))'.

Где он там неизвестный тип нашёл непонятно.
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066151
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

Увы, на 14 стандарте это работает, на 11 нет, проверял на g++ 5.2.1

Можно попробовать так, decltype там не нужен, он нужен лишь для выведения типа из какого-либо выражения, как раз если trailing type вывести можно одним выражением.
Код: plaintext
1.
2.
3.
4.
5.
template <typename t_class, typename... t_arguments>
    auto Signal( void (t_class::*ptr)(t_arguments...) ) -> void (t_class::*)(t_arguments...)
{
    return static_cast<void (t_class::*)(t_arguments...)>(ptr);
}
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066155
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще, нахрена такое извращение, когда есть (std|boost)::function???
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066176
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZА вообще, нахрена такое извращение, когда есть (std|boost)::function???
А это система слотов и сигналов из Qt5, которая теперь аля boost::signals. Я её не упоминал напрямую, что бы расширить аудиторию обсуждения. :)

Нам нужно только написать функцию Signal.

Кстати, Ваш последний код откомпилировался. Спасибо. :)

Я так понимаю, тут нельзя избавиться от повтора названия класса Foo?
Код: plaintext
1.
Connect( Signal<Foo, int>(&Foo::MySignal) );
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066193
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravNekZА вообще, нахрена такое извращение, когда есть (std|boost)::function???
А это система слотов и сигналов из Qt5, которая теперь аля boost::signals. Я её не упоминал напрямую, что бы расширить аудиторию обсуждения. :)


Совсем ни разу. Это хитрая и гибкая реализация функторов с возможностью частичного применения через std::bind.

petravЯ так понимаю, тут нельзя избавиться от повтора названия класса Foo?
Код: plaintext
1.
Connect( Signal<Foo, int>(&Foo::MySignal) );



Ну, если бы можно это было бы как-то завернуть в автовыведение типа, то наверное.
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066203
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZpetravпропущено...

А это система слотов и сигналов из Qt5, которая теперь аля boost::signals. Я её не упоминал напрямую, что бы расширить аудиторию обсуждения. :)


Совсем ни разу. Это хитрая и гибкая реализация функторов с возможностью частичного применения через std::bind.

Да нет же. Это я, формулируя исходную задачу, на самом деле описывал систему слоты-сигналы из Qt5. И возникшую с ними проблему.

Думаю, std::function туда ну ни как не прикрутить. :)

NekZpetravЯ так понимаю, тут нельзя избавиться от повтора названия класса Foo?
Код: plaintext
1.
Connect( Signal<Foo, int>(&Foo::MySignal) );



Ну, если бы можно это было бы как-то завернуть в автовыведение типа, то наверное.

Как это сделать у меня идей нет. :(
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066492
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boost::signals2 ?
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066527
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexy_blackboost::signals2 ?
Да. Раньше в Qt это решали с помощью собственного макропроцессора + кодагенератора. Теперь вот добавили поддержку чистого С++. Даже макрос «slot» уже не обязателен.
...
Рейтинг: 0 / 0
Взятие адреса перегруженного метода класса
    #39066990
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravВ шаблонную функцию нужно передать адрес перегруженного метода некоторого класса:
...
Это заведомо неверно, но у меня даже идей не возникает как это сделать правильнее. А у вас идеи есть?

Код даже не читал.

Если у тебя код шаблонный, то ты просто можешь без передачи адреса функции её вызывать по имени
везде, где нужно. Компилятор сам её найдёт, а если не найдёт -- ругнётся.

Это конечно, если делать это нужно исключительно в compile-time.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Взятие адреса перегруженного метода класса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]