Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> (g++)указатель на шаблонную функцию 
V
    Опции темы
GoldFinch
Дата 27.11.2010, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Код

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}

template<class T>
void method_to_fn(T* that)
{
    that->bar();
}

#include <iostream>

struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};

int main()
{
    //function_with_callback((callback_t)method_to_fn<Foo>, NULL);
    function_with_callback((callback_t)static_cast<void(*)(Foo*)>(method_to_fn<Foo>), NULL);
}

этот код работает.
а если раскомментировать 22ю строчку, то он будет работать в MSVC, а g++ выдаст ошибку 
Код

 error: insufficient contextual information to determine type

link1, link2
при этом на самом деле причина ошибки в том, что g++ считает method_to_fn перегруженной функцией, и по этому нужен static_cast чтобы выбрать "перегрузку".

почему так?
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 15:26 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:20 Найти цитируемый пост)
Код
(callback_t)static_cast<void(*)(Foo*)>(method_to_fn<Foo>)
Красотища...
Чистой воды UB.


Это сообщение отредактировал(а) Леопольд - 27.11.2010, 15:38


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
boostcoder
Дата 27.11.2010, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(GoldFinch @  27.11.2010,  15:20 Найти цитируемый пост)
g++ выдаст ошибку 

хз о чем Вы...
http://liveworkspace.org/code/f7dde36deec8...4dc382d0b33ea77
PM WWW   Вверх
GoldFinch
Дата 27.11.2010, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



boostcoder, какая там версия гцц?
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



GoldFinch, пока ещё не смог понять из кода, что именно надо...


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, не страшно

boostcoder, похоже действительно в 4.5 это починили, это какая-то особенность С++0х 
PM MAIL ICQ   Вверх
boostcoder
Дата 27.11.2010, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(GoldFinch @  27.11.2010,  15:35 Найти цитируемый пост)
какая там версия гцц? 

4.5.1
PM WWW   Вверх
Леопольд
Дата 27.11.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:38 Найти цитируемый пост)
Леопольд, не страшно
Может это?
Код
template<typename T>
void function_with_callback(void(*callback)(T*), T * param)
{
    callback(param);
}

template<class T>
void method_to_fn(T* that)
{
    that->bar();
}

#include <iostream>

struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};

void foo(char const* str)
{
   std::cout << str << '\n';
}

int main()
{
    Foo inst;
    function_with_callback(method_to_fn<Foo>, &inst);
    function_with_callback(foo, "hello!");
}
http://liveworkspace.org/code/a442dfbbd883cfe0d08df7c6a98cd0db


Это сообщение отредактировал(а) Леопольд - 27.11.2010, 15:47


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, не угадали.
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:44 Найти цитируемый пост)
Леопольд, не угадали. 
Тогда, может объясните по человечески? Потому что, если избавиться от UB, получается именно это...



--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Цитата(boostcoder @ 27.11.2010,  16:32)
Цитата(GoldFinch @  27.11.2010,  15:20 Найти цитируемый пост)
g++ выдаст ошибку 

хз о чем Вы...
http://liveworkspace.org/code/f7dde36deec8...4dc382d0b33ea77

эээ нееет) это чит smile
потому что когда там обе строчки, версия со статик-кастом позволяет работать версии без статик-каста
Код

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
template<class T>
void method_to_fn(T* that)
{
    that->bar();
}

#define CODE_VARIANT 1

#include <iostream>
struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};
int main()
{
#if CODE_VARIANT == 1
    function_with_callback((callback_t)method_to_fn<Foo>, NULL);
#else
    function_with_callback((callback_t)static_cast<void(*)(Foo*)>(method_to_fn<Foo>), NULL);
#endif
}


http://liveworkspace.org/code/9b7c03115be3...2fc50ee142cd60e

Добавлено через 2 минуты и 8 секунд
Леопольд, this тут вообще ни при чем, а нулевой this - это вроде не UB.
В любом случае, это к проблеме отношения не имеет, добавляйте туда объект если хотите.

Добавлено через 4 минуты и 8 секунд
btw, liveworkspace.org всем хорош, только там табуляция 3 символа =\ хотелось бы 4 %)
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:51 Найти цитируемый пост)
Леопольд, this тут вообще ни при чем, а нулевой this - это вроде не UB.
Показалось... Там ведь не разыменовывается указатель.

UB приводить указатели на функцию, static_cast неспроста не даёт этого делать.
Это UB в действии http://liveworkspace.org/code/9b7c03115be3...2fc50ee142cd60e

Использовать С-ишное приведение в С++, зачем?
Код
#include <cstdlib>

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}

template<class T>
void method_to_fn(void * param)
{
    static_cast<T*>(param)->bar();
}

#define CODE_VARIANT 2

#include <iostream>
struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};
int main()
{
    function_with_callback(method_to_fn<Foo>, NULL);
}

Наверное, это ближе всех:
http://liveworkspace.org/code/c631f5ef9be4...477373840e60b9a
static_cast из void * , тоже самое что и reinterpret_cast. Только выглядит безобиднее.

На мой взгляд, не особо много смысла. Зачем это надо?

Это сообщение отредактировал(а) Леопольд - 27.11.2010, 16:34


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, С-style cast тоже ни при чем. Что вы, приведения типов функций никогда чтоле не видели %)

PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  16:21 Найти цитируемый пост)
Что вы, приведения типов функций никогда чтоле не видели
В С++ не видел. Про С не могу сказать, может там это легально.

Это сообщение отредактировал(а) Леопольд - 27.11.2010, 16:24


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, впрочем, спасибо за подсказку

убрал из сигнатуры method_to_fn шаблонный тип, "перегрузки" исчезли, и всё заработало

Код

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
template<class T>
void method_to_fn(void* that)
{
    static_cast<T*>(that)->bar();
}

#include <iostream>
struct Foo
{
    void bar() { std::cout << "test OK\n"; }
};
int main()
{
    function_with_callback(method_to_fn<Foo>, NULL);
}


PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Код
typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}

template<class T>
void method_to_fn(void* that)
{
    static_cast<T*>(that)->bar();
}

#include <iostream>
struct Bar
{
   int field;  
} inst;

struct Foo
{
   int field; 
    void bar() { std::cout << "test OK\n"; field = 1234; }
};

int main()
{
    function_with_callback(method_to_fn<Foo>, &inst);
    std::cout << inst.field <<std::endl;
    
    return 0;
}
Ни одного ворнинга.
http://liveworkspace.org/code/bf8a2fa6241c...c42f3af3acb7ab2

Это сообщение отредактировал(а) Леопольд - 27.11.2010, 16:45


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, помоему я написал тожесамое

Добавлено через 7 минут и 57 секунд
Всем спасибо за участие, вопрос решен.


---------

собственно ради чего это всё затевалось:
Код

//------- Third-party library code ------

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}

//------- Our library code --------

template<class T, void (T::*m)()>
void method_to_fn(void* that)
{
    (static_cast<T*>(that)->*m)();
}

//------- test ------

#include <iostream>

int main()
{
    struct Foo
    {
        void bar() { std::cout << "Foo::bar OK\n"; }
    };

    Foo foo;
    
    function_with_callback(method_to_fn<Foo, &Foo::bar>, &foo);
}


PM MAIL ICQ   Вверх
mes
Дата 27.11.2010, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  27.11.2010,  15:47 Найти цитируемый пост)
собственно ради чего это всё затевалось:

угу.. нажить проблемы :
http://liveworkspace.org/code/5b05551a3ef0...3e10f277664cf41



--------------------
PM MAIL WWW   Вверх
Леопольд
Дата 27.11.2010, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  16:47 Найти цитируемый пост)
Леопольд, помоему я написал тожесамое
Не совсем, я показал что не так с static_cast ( mes показал тоже самое). Можно легко получить UB, компилятор ничем не сможет помочь.
вот ещё UB, компилятор проглотил не поперхнувшись
Код
//------- Third-party library code ------
typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
//------- Our library code --------
template<class T, void (T::*m)()>
void method_to_fn(void* that)
{
    (static_cast<T*>(that)->*m)();
}
//------- test ------

#include <iostream>

int main()
{
    struct Foo
    {
        int i;
        void bar() { std::cout << "Foo::bar OK\n"; reinterpret_cast<std::string&>(i) = "Foo1::bar FALSE\n"; }
    };

    struct Foo1
    {
        std::string s;
        void bar(void) { std::cout << s; }
        Foo1() : s("Foo1::bar OK\n") {}
    };

    Foo1 foo;
    
    function_with_callback(method_to_fn<Foo, &Foo::bar>, &foo);

    foo.bar();
}
http://liveworkspace.org/code/43f2050c7444c9c80504d1240d20c1f3

Надо написать шаbлон оbёртку, который включит типизацию оbратно.


Это сообщение отредактировал(а) Леопольд - 27.11.2010, 19:59


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



mes, зачем было городить такой сложный код, передали бы туда сразу int* например, оно бы вообще упало %)

предложите тогда лучший код, чтоб работал в гцц
PM MAIL ICQ   Вверх
mes
Дата 27.11.2010, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  27.11.2010,  22:15 Найти цитируемый пост)
mes, зачем было городить такой сложный код, передали бы туда сразу int* например, оно бы вообще упало %)

так в этом случае Вы могли бы свалить на ССЗБ.. а тут вы вроде и метод правильно получили... да не тот.. smile

Добавлено через 3 минуты и 20 секунд
единственный безопасный способ получить void*_адрес метода.. это взять его у статической прокси функции..
(т.е. без лишних телодвижений  увы никак)..



--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 27.11.2010, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



поясню, этот код нужен чтобы передавать коллбэки на С++ в библиотеки с Си-интерфейсом.
естественно у function_with_callback будет в сигнатуре void() и void* и на каком-то этапе надо будет привести T* в void*

кстати пожалуй более интересный вариант это
Код

//------- Third-party library code ------
typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
//------- Our library code --------
template<class T>
void ftor_to_fn(void* that)
{
    (*(T*)that)();
}
//------- test ------
#include <iostream>
#include <boost/bind.hpp>
int main()
{
    struct Foo
    {
        void operator()() { std::cout << "test #1 OK\n"; }
        void bar() { std::cout << "test #2 OK\n"; }
        void baz() { std::cout << "test #3 OK\n"; }
    };
    Foo foo;
    
    function_with_callback(ftor_to_fn<Foo>, &foo);

    auto f1 = boost::bind(&Foo::bar, &foo);
    function_with_callback(ftor_to_fn<decltype(f1)>, &f1);
    
    auto f2 = [&foo](){ foo.baz(); };
    function_with_callback(ftor_to_fn<decltype(f2)>, &f2);
}


Добавлено через 4 минуты и 54 секунды
mes, я не понимаю. 
вы написали 
Код

function_with_callback(method_to_fn<Foo, &Foo::bar>, &afoo); // тип afoo != Foo

вторым аргументом function_with_callback может быть чтоугодно, 
по этому подразумевается что пользователь должен сам убедиться что если 1й аргумент это адаптер для T, то 2й аргумент имеет тип T*
PM MAIL ICQ   Вверх
mes
Дата 27.11.2010, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  27.11.2010,  22:30 Найти цитируемый пост)
что пользователь должен сам убедиться что если 1й аргумент это адаптер для T, то 2й аргумент имеет тип T*

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

Добавлено через 1 минуту и 30 секунд
Цитата(GoldFinch @  27.11.2010,  22:30 Найти цитируемый пост)
кстати пожалуй более интересный вариант это

этот уже похож на нормальный.. нужно внимательней посмотреть.. 



--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 27.11.2010, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



вот тут вот надо обязательно использовать дополнительную переменную
Цитата(GoldFinch @  28.11.2010,  00:30 Найти цитируемый пост)
    auto f2 = [&foo](){ foo.baz(); };
    function_with_callback(ftor_to_fn<decltype(f2)>, &f2);

этим можно воспользоваться, и написать вот так вот:

Код

//------- Third-party library code ------
typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
//------- Our library code --------
#include <utility>
template<class Functor>
std::pair<void(*)(void*), void*> ftor_to_fn_pair(Functor&& ftor)
{
    struct Wrap
    {
        static void invoke(void* that)
        {
            (*(Functor*)that)();
        }
    };    
    return std::pair<void(*)(void*), void*>(&Wrap::invoke, &ftor);
}
//------- test ------
#include <iostream>
int main()
{
    struct Foo
    {
        void bar() { std::cout << "test OK, x = " << x << "\n"; }
        int x;
        Foo(int x) : x(x) {}
    };
    Foo foo(42);
   
    auto f = ftor_to_fn_pair([&foo](){ foo.bar(); });
    function_with_callback(f.first, f.second);
}

вроде это наиболее типобезопасный вариант

Добавлено через 3 минуты и 24 секунды
интересно правда как этот код вообще работает %)
я не очень понимаю что есть rvalue-reference, и почему значение этой лямбды продолжает жить %)
PM MAIL ICQ   Вверх
mes
Дата 27.11.2010, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  27.11.2010,  22:51 Найти цитируемый пост)
вроде это наиболее типобезопасный вариант

мне кажется тут еще можно подумать..

Добавлено через 1 минуту и 7 секунд
идти не в сторону получения пары, а предоставлении обертки над  function_with_callback


--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 28.11.2010, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



... и да, использование дополнительной локальной переменной делает всё совершенно неюзабельным =\
проблема в том, что она должна где-то жить, чтобы указатель на нее был валидным.

а типичный пример использования это
Код

    Foo* foo = get_Foo_instance();

    void set_handler(void(*)(void*), void*);
    set_handler(adapt_method_to_fn(&Foo::method), foo);



Добавлено через 1 минуту и 18 секунд
пара полезна тем что она гарантирует то, что оба агрумента взяты из одного источника, который может проверить их совместимость

Добавлено через 4 минуты и 26 секунд
Цитата(mes @  28.11.2010,  00:57 Найти цитируемый пост)
предоставлении обертки над  function_with_callback 

это наиболее очевидный и понятный вариант, но мы его не рассматриваем.

мне интересно создание одной реюзабельной функции которая позволила бы делать обертки для методов

Добавлено через 12 минут и 11 секунд
более того, есть случаи, когда написание обертки практически невозможно
Код

void fn(void(*callback)(void*), void* param, const char* format, ... /*ellipsis*/);

PM MAIL ICQ   Вверх
mes
Дата 28.11.2010, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  27.11.2010,  23:05 Найти цитируемый пост)
мне интересно создание одной реюзабельной функции которая позволила бы делать обертки для методов

ну а что мешает сделать это проксю единой для всех подходящих функций ?
 smile

Добавлено @ 00:28
Цитата(GoldFinch @  27.11.2010,  23:05 Найти цитируемый пост)
более того, есть случаи, когда написание обертки практически невозможно

ну еллипсис впринципе можно тоже разгрузить..

другой вопрос - нужно ли это..

Это сообщение отредактировал(а) mes - 28.11.2010, 00:34


--------------------
PM MAIL WWW   Вверх
mes
Дата 28.11.2010, 00:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



вот примерно о чем я предлагал  (на основе вашего кода)
Код

template <typename F1, typename F2>
void proxy (F1 && f1, F2&&  f2)
{
    struct Wrap
    {
        static void invoke(void* that)
        {
            (*(F2*)that)();
        }
    }; 
    f1 (&Wrap::invoke, &f2);
}

 Foo foo(42);
    
 proxy ( std::bind(fcb,_1,_2) 
       , std::bind(&Foo::bar,&foo) );


fcb - function_with_callback


--------------------
PM MAIL WWW   Вверх
Леопольд
Дата 28.11.2010, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



mes, думается, это надо для реального проекта. Навряд ли rvalue ссылки можно в нём использовать. Правда, ничто не мешает из заменить на оbычные... smile


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 28.11.2010, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Леопольд @  27.11.2010,  23:59 Найти цитируемый пост)
Навряд ли rvalue 

я их у тс перенял smile раз ему можно , значит все в порядке  smile

Добавлено @ 01:03
тем более они к теме напрямую не относятся..
и вопрос о надежности уже был также поднят тс.. но я например не в состоянии на него ответить.. поэтому пока беру как есть smile

Добавлено @ 01:04
суть в самом вызове proxy, чтоб не приходилось в ручную заниматься "подбором" параметров.. 


Это сообщение отредактировал(а) mes - 28.11.2010, 01:05


--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 28.11.2010, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



не, в реальной ситуации у function_with_callback будет еще куча параметров, так что никакой реюзабельности не получится
PM MAIL ICQ   Вверх
mes
Дата 28.11.2010, 01:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  28.11.2010,  00:06 Найти цитируемый пост)
не, в реальной ситуации у function_with_callback будет еще куча параметров, так что никакой реюзабельности не получится 

ну да, а bind тогда нам зачем ?!  smile 

допустим fcb имеет такой вид :
Код

typedef void(*callback_t)(void*);
void fcb (int i, float f, void* param, callback_t callback, int j)
{
    callback(param);
}

тогда вызов может иметь такой вид :
Код

  proxy ( std::bind(fcb, 4, 6.3, _2, _1, 8 ) 
          , std::bind(&Foo::bar,&foo) );

где 4,6.3,8 значения параметров, которые мы должны передать функции помимо колбяка.. 
 smile 


--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 28.11.2010, 02:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



м.. ну да.. только выглядит ужасно  =\
PM MAIL ICQ   Вверх
mes
Дата 28.11.2010, 02:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  28.11.2010,  01:23 Найти цитируемый пост)
м.. ну да.. только выглядит ужасно  =\ 

..
Код

 auto f = ftor_to_fn_pair(bind (&Foo::bar, &foo) );
 fcb (4, 6.3, f.second, f.first, 8);

Код

 proxy ( std::bind(fcb, 4, 6.3, _2, _1, 8 ) 
       , std::bind(&Foo::bar,&foo) );

ну не знаю какой из кодов выглядит ужасней 
smile 

Это сообщение отредактировал(а) mes - 28.11.2010, 02:41


--------------------
PM MAIL WWW   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0838 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.