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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> сохранение параметров variadic template, variadic template 
V
    Опции темы
borisbn
Дата 4.12.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



День добрый.
Разбираюсь с variadic template. Захотелось набрасать такую штуку
Код

#include <iostream>

template < class C, class Res, class ...Args >
struct Delegate
{
    Res (C::*m_fun)(Args...);
    C * m_obj;
    Args m_args;       // (1) 
//    Args... m_args;    // (2)

    Delegate( Res (C::*fun)(Args...), C * obj, Args... args )
        : m_fun( fun ), m_obj( obj ), m_args( args... )
    {
    }
    Res run() {
        return (m_obj->*m_fun)( m_args... );
    }
};

template < class C, class Res, class ...Args >
struct Delegate< C, Res, Args... > delegate( Res (C::*fun)(Args...), C * obj, Args... args )
{
    return Delegate<C, Res, Args...>( fun, obj, args... );
}

struct A
{
    int foo( int x, int y ) { return x + y; }
};

int main()
{
    A a;
    auto d = delegate( &A::foo, &a, 20, 22 );
    int y = d.run();
    std::cout << y << std::endl;
}

http://liveworkspace.org/code/4299c32fb77d...2ea687a8a7b0942

получаю ошибки:
в случае (1)
Цитата
parameter packs not expanded with '...'

в случае (2)
Цитата
expected unqualified-id before '...' token

скорее всего, ни то ни то неправильно, но, я думаю, вы понимаете, что хотелось сделать smile
Вопрос: как сохранить переменное количество аргументов ?
Спасибо.

P.S. bind, function не предлагать. Я просто разбираюсь, и мне нужно не решение конкретной задачи, а научиться пользоваться variadic template'ми

P.P.S. Эти темы 
http://stackoverflow.com/questions/1989552...-expand-identif
http://stackoverflow.com/questions/4691657...ut-expanding-it
http://www.cplusplus.com/forum/general/47084/
смотрел, и, в общем-то, там похожие вопросы, но там решается немного другие задачи

Это сообщение отредактировал(а) borisbn - 4.12.2011, 14:38


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 4.12.2011, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  4.12.2011,  14:36 Найти цитируемый пост)
Вопрос: как сохранить переменное количество аргументов ?

в std::tuple<> или boost.tuple или boost.fusion::vector
PM WWW   Вверх
mes
Дата 4.12.2011, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(borisbn @  4.12.2011,  13:36 Найти цитируемый пост)
Вопрос: как сохранить переменное количество аргументов ?

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

Добавлено через 47 секунд
Цитата(boostcoder @  4.12.2011,  15:22 Найти цитируемый пост)
boost.fusion::vector 

он с вариадиками же не работает ? или уже начал ?



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


pattern`щик
****


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

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



Цитата(mes @  4.12.2011,  16:26 Найти цитируемый пост)
он с вариадиками же не работает ? или уже начал ?

при использовании gcc-4.5.1-4.5.2 я писал адаптер. в 4.6.1-4.6.2 вроде уже должен. но не проверял.

адаптер:
Код

template<typename... Args>
struct from_variadic;

template<typename T, typename... Args>
struct from_variadic<T, Args...> {
   typedef typename
   boost::mpl::push_front<
      typename from_variadic<Args...>::type
      , T
   >::type type;
};

template<typename T>
struct from_variadic<T> {
   typedef boost::mpl::vector<T> type;
};

template <>
struct from_variadic<> {
   typedef boost::mpl::vector<> type;
};



Добавлено через 3 минуты и 20 секунд
Цитата(boostcoder @  4.12.2011,  16:31 Найти цитируемый пост)
в 4.6.1-4.6.2 вроде уже должен. но не проверял.

ан нет. все еще недопилено:
Цитата

source.cpp:14:33: sorry, unimplemented: cannot expand 'Args ...' into a fixed-length argument list

http://liveworkspace.org/code/662ad39edfe8...c95296da8dc6422

Добавлено через 3 минуты и 44 секунды
значит с использованием адаптера.
PM WWW   Вверх
mes
Дата 4.12.2011, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  4.12.2011,  15:31 Найти цитируемый пост)
адаптер:


Цитата(boostcoder @  4.12.2011,  15:31 Найти цитируемый пост)
template<typename T>
struct from_variadic<T> {
   typedef boost::mpl::vector<T> type;
};

не лишний ли в этом ряду ?



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


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(boostcoder @  4.12.2011,  16:22 Найти цитируемый пост)
в std::tuple<> или boost.tuple или boost.fusion::vector

это первое, что советуют на СОшке. И с этим, вроде, всё понятно. Как теперь в ф-ции Delegate::run() вызвать
Код
(m_obj->*m_fun)( ??? );

если m_fun - указатель на обычную ф-цию, которая принимает два инта (к примеру), а не tuple...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 4.12.2011, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(borisbn @  4.12.2011,  15:48 Найти цитируемый пост)
 Как теперь в ф-ции Delegate::run() вызвать

Цитата(mes @  4.12.2011,  15:26 Найти цитируемый пост)
по реализации первым напрашивается обернуть его в структуру, чтоб получить новый тип, и для полученого специализировать  шаблонный инвокер.. (функцию обертку для применения аргументов к нужной функции)..





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


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(mes @  4.12.2011,  16:52 Найти цитируемый пост)
по реализации первым напрашивается обернуть его в структуру, чтоб получить новый тип, и для полученого специализировать  шаблонный инвокер.. (функцию обертку для применения аргументов к нужной функции)..

в прошлый рах раза два прочитал - не понял. Сейчас ещё раз перечитал раза три - рез-т тот же. 
"обернуть его в структуру, чтоб получить новый тип" - до сюда ясно
"и для полученого специализировать  шаблонный инвокер.. " -  smile 
можете (если не сложно) в моей поделке добавить чего там не хватает ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 4.12.2011, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  4.12.2011,  16:48 Найти цитируемый пост)
 Как теперь в ф-ции Delegate::run() вызвать

http://www.boost.org/doc/libs/1_48_0/libs/...ons/invoke.html
только при помощи boost::fusion::push_front() сначала вставь адрес самого объекта.

псевдокод:
Код

boost::fusion::vector< ... > args;
res = boost::fusion::invoke(m_fun, boost::fusion::push_front(args, m_obj));


Добавлено через 9 минут и 53 секунды
да, и прочти про семейство функций invoke(). к счастью их всего три smile 
PM WWW   Вверх
borisbn
Дата 4.12.2011, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



пробую так
Код

template < class C, class Res, class ...Args >
struct Delegate
{
    Res (C::*m_fun)(Args...);
    C * m_obj;
//    Args m_args;       // (1) 
//    Args... m_args;    // (2)
//    boost::fusion::vector<Args...> m_args;
    typename from_variadic< Args... >::type m_args;
   
    Delegate( Res (C::*fun)(Args...), C * obj, Args... args )
        : m_fun( fun ), m_obj( obj ), m_args( args... )
    {
    }
    Res run()
    {
        //return (m_obj->*m_fun)( m_args... );
        return boost::fusion::invoke( m_fun, boost::fusion::push_front( m_args, m_obj ) );  
    }
};

http://liveworkspace.org/code/fd421efe0c12...ce89a5764890d66
выдаётся миллион ошибок типа
Цитата

Compilation finished with errors:
In file included from boost/mpl/push_front.hpp:18:0,
                 from boost/mpl/front_inserter.hpp:18,
                 from boost/mpl/aux_/inserter_algorithm.hpp:19,
                 from boost/mpl/remove_if.hpp:25,
                 from boost/mpl/remove.hpp:18,
                 from boost/function_types/components.hpp:45,
                 from boost/function_types/is_function.hpp:14,
                 from boost/fusion/functional/invocation/invoke.hpp:34,
                 from source.cpp:6:
boost/mpl/aux_/push_front_impl.hpp: In instantiation of 'boost::mpl::push_front_impl<boost::fusion::fusion_sequence_tag>::apply<boost::fusion::vector<int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, int>':
boost/mpl/push_front.hpp:29:8:   instantiated from 'boost::mpl::push_front<boost::fusion::vector<int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, int>'
source.cpp:17:12:   instantiated from 'from_variadic<int, int>'
source.cpp:38:45:   instantiated from 'Delegate<A, int, int, int>'
source.cpp:65:44:   instantiated from here



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 4.12.2011, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



какой-то баг похоже в бусте появился... или что-то изменилось, ибо банальный код перестал работать.
http://liveworkspace.org/code/ceeb6831c613...fc13be57b084114

обратите внимание на:
Цитата

boost/mpl/aux_/push_front_impl.hpp:41:9: error: no matching function for call to 'assertion_failed(mpl_::failed************ (boost::mpl::push_front_impl<boost::fusion::fusion_sequence_tag>::apply<boost::fusion::vector<double, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, int>::REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST::************)(boost::fusion::vector<double, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>))'

PM WWW   Вверх
boostcoder
Дата 4.12.2011, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(boostcoder @  4.12.2011,  18:07 Найти цитируемый пост)
какой-то баг похоже в бусте появился

ааа ,нет. это я затупил)

Добавлено через 3 минуты и 4 секунды
borisbn, позже доковыряю. спешу.
http://liveworkspace.org/code/35b5fd6a6f3d...fac6dbcced127d1

Добавлено через 11 минут и 47 секунд
все же доковырял.
держи: http://liveworkspace.org/code/f1471c281476...54f545431246d06
Код

#include <iostream>

#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_front.hpp>

#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/container/vector/vector_fwd.hpp>
#include <boost/fusion/include/vector_fwd.hpp>
#include <boost/fusion/algorithm/transformation/push_front.hpp>
#include <boost/fusion/include/push_front.hpp>
#include <boost/fusion/functional/invocation/invoke.hpp>

template<typename... Args>
struct from_variadic;

template<typename T, typename... Args>
struct from_variadic<T, Args...> {
   typedef typename
   boost::mpl::push_front<
   typename from_variadic<Args...>::type
   , T
   >::type type;
};

template<typename T>
struct from_variadic<T> {
   typedef boost::mpl::vector<T> type;
};

template <>
struct from_variadic<> {
   typedef boost::mpl::vector<> type;
};

template < class C, class Res, class ...Args >
struct Delegate {
   Res (C::*m_fun)(Args...);
   C * m_obj;

   typedef typename boost::fusion::result_of::as_vector<
      typename from_variadic<Args...>::type
   >::type args_t;

   args_t m_args;

   Delegate( Res (C::*fun)(Args...), C * obj, Args... args )
      :m_fun(fun)
      ,m_obj(obj)
      ,m_args(args...)
   {}

   Res run() {
      return boost::fusion::invoke( m_fun, boost::fusion::push_front( m_args, m_obj ) );
   }
};

template < class C, class Res, class ...Args >
struct Delegate< C, Res, Args... >
delegate( Res (C::*fun)(Args...), C * obj, Args... args ) {
   return Delegate<C, Res, Args...>( fun, obj, args... );
}

struct A {
   int foo( int x, int y ) { return x + y; }
};

int main() {
   A a;
   auto d = delegate( &A::foo, &a, 20, 22 );
   int y = d.run();
   std::cout << y << std::endl;
}


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


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


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

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



вот тут тоже есть интересное :
http://beardedcodewarrior.net/2011/05/12/c...iadic-for_each/


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


pattern`щик
****


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

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



mes, угу, интересно.

Добавлено через 2 минуты и 15 секунд
забавно smile
PM WWW   Вверх
boostcoder
Дата 5.12.2011, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



borisbn, что-то ты как-то внезапно пропал... вариант решения не устроил?
PM WWW   Вверх
borisbn
Дата 5.12.2011, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(boostcoder @  5.12.2011,  01:54 Найти цитируемый пост)
 что-то ты как-то внезапно пропал... вариант решения не устроил?

Всё гораздо проще - заснул smile (только из командировки...)
Вариант устроил (даже плюсанул). Спасибо.

Правильно ли я понимаю, что invoke bind'ит по-очереди параметры к указанной ф-ции ?

P.S. Жаль, что для такой простой (на мой неквалифицированный взгляд) задачи, как сохранение параметров var.template, нужна такая орава непростых классов (boost::mpl::push_front, boost::mpl::vector, boost::fusion::result_of::as_vector, boost::fusion::invoke). Плюс два квалифицированных программиста (mes + boostcoder).
Ну... это так. Мысли вслух. 


На самом деле ещё раз спасибо. Закрываю.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 5.12.2011, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  5.12.2011,  09:23 Найти цитируемый пост)
Правильно ли я понимаю, что invoke bind'ит по-очереди параметры к указанной ф-ции ?

честно? - даже не разбирался) фьюжн очень тяжело читается  smile 

Цитата(borisbn @  5.12.2011,  09:23 Найти цитируемый пост)
нужна такая орава непростых классов (boost::mpl::push_front, boost::mpl::vector, boost::fusion::result_of::as_vector

эти нужны только по тому, что компилятор пока не умеет разворачивать вариадик в список параметров. но это пока.
а в будущем, можно будет использовать std::tuple<...> и boost.fusion::invoke.
PM WWW   Вверх
mes
Дата 5.12.2011, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(borisbn @  5.12.2011,  08:23 Найти цитируемый пост)
задачи, как сохранение параметров var.template, нужна такая орава

для этой задачи достаточно стандартного tuple

Цитата(borisbn @  5.12.2011,  08:23 Найти цитируемый пост)
непростых классов (boost::mpl::push_front, boost::mpl::vector, boost::fusion::result_of::as_vector, boost::fusion::invoke)

в принципе нужен только аналог boost::fusion::invoke для tuple, тогда все это не нужно.. 




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


pattern`щик
****


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

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



Цитата(boostcoder @  5.12.2011,  09:45 Найти цитируемый пост)
компилятор пока не умеет разворачивать вариадик в список параметров

хотя, не знаю как это правильно объяснить... может mes подскажет.

Добавлено через 6 минут и 20 секунд
кстати, на гитхабе как-то встречал форк реализации то-ли boost.mpl то-ли boost.fusion с поддержкой вариадиков. но что-то особо не вдумывался для чего это. а наверное для того чтоб обходится без приведенных мною адаптеров..
PM WWW   Вверх
borisbn
Дата 5.12.2011, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Хммм. А у этой конструкции есть ограничения...
Например, нельзя "сопрячь" констовую ссылку и объект:
Код

struct A {
   void foo( int x, int y, const std::string & str ) {
       std::cout << str << " " << x + y << std::endl;
   }
};

int main() {
   A a;
   auto d = delegate( &A::foo, &a, 20, 22, std::string( "Hi!" ) );
   d.run();
}


http://liveworkspace.org/code/4be6766d51d7...83c0b2b98c265c9
ругается
Цитата

Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:75:65: error: no matching function for call to 'delegate(void (A::*)(int, int, const string&), A*, int, int, std::string)'
source.cpp:75:65: note: candidate is:
source.cpp:63:1: note: template<class C, class Res, class ... Args> Delegate<C, Res, Args ...> delegate(Res (C::*)(Args ...), C*, Args ...)
source.cpp:75:65: error: unable to deduce 'auto' from '<expression error>'

если же сделать foo( int x, int y, std::string str ) - работает...



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 5.12.2011, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  5.12.2011,  10:20 Найти цитируемый пост)
нельзя "сопрячь" констовую ссылку и объект

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

Добавлено через 14 минут и 39 секунд
ааа, нет!
сигнатура метода при вызове delegate() выводится из сигнатуры указываемого метода. а подставляемые аргументы не совпадают.

Добавлено через 14 минут и 58 секунд
но посредник там все равно есть smile 

Это сообщение отредактировал(а) boostcoder - 5.12.2011, 10:35
PM WWW   Вверх
boostcoder
Дата 5.12.2011, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(boostcoder @  5.12.2011,  09:48 Найти цитируемый пост)
может mes подскажет.

нет, не хочет он общаться... smile 
PM WWW   Вверх
mes
Дата 5.12.2011, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  5.12.2011,  15:17 Найти цитируемый пост)
нет, не хочет он общаться...

у меня пока не было времени обдумать и ответить .. smile

Добавлено через 6 минут и 57 секунд
Цитата(boostcoder @  5.12.2011,  08:48 Найти цитируемый пост)
хотя, не знаю как это правильно объяснить... может mes подскажет

ну как граммотно это сказать  тоже не знаю..  проблема стоит в конвертации списка аргументов переменного размера в список фиксированного размера..

Добавлено через 8 минут и 9 секунд
под проблемой подразумевается создание fusion-контейнера  непосредственно из вариадика..

Добавлено через 10 минут и 7 секунд
std::bind хранит аргументы в tuple, и имеет средства его инвокинга, но это находится в _приватной_части_ и "недоступно" пользователю.. 



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


pattern`щик
****


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

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



да, кстати, вариадик разворачивается в std::tuple<> smile 
я думал что это не проблема fusion/mpl а проблема компилятора..
Код

#include <tuple>

template<typename... Args>
struct type {
   typedef std::tuple<Args...> args_type;
};

int main() {
   type<int> t1;
   type<int, double> t2;
   type<int, double, const char*> t3;
}


http://liveworkspace.org/code/e36900262a55...c1cc5fd45ccf8bf

Добавлено через 2 минуты и 26 секунд
mes, вчера же Вы дали ссылку на блог. я прочел, но так и не отметил тот факт что вариадики и кортежи дружат.
PM WWW   Вверх
mes
Дата 5.12.2011, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  5.12.2011,  18:05 Найти цитируемый пост)
да, кстати, вариадик разворачивается в std::tuple<> 

ммм.. позвольте уточнить Вы были не в курсе, что можно из аргументов вариадика построить std::tuple ?


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


pattern`щик
****


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

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



Цитата(mes @  5.12.2011,  19:11 Найти цитируемый пост)
не в курсе, что можно из аргументов вариадика построить std::tuple ?

да. точнее сказать, я полагал что при использовании std::tuple компилятор будет так же говорить что что-то там не реализовано.


Цитата(mes @  5.12.2011,  18:42 Найти цитируемый пост)
проблема стоит в конвертации списка аргументов переменного размера в список фиксированного размера

а разве это не тот случай?
Код

#include <iostream>
#include <tuple>

template<typename... Args>
struct type {
   typedef int args_t[sizeof...(Args)];
   args_t args;
   
   type(Args... a)
      :args{a...}
   {}
};

typedef type<int> tuple1;
typedef type<int, int> tuple2;
typedef type<int, int, int> tuple3;

int main() {
   tuple1 t1(1);
   tuple2 t2(1,2);
   tuple3 t3(1,2,3);
   
   std::cout
   << sizeof(tuple1::args_t) << std::endl
   << sizeof(tuple2::args_t) << std::endl
   << sizeof(tuple3::args_t) << std::endl
   ;
}


http://liveworkspace.org/code/0994d2d997f7...495d11a7c3b2a3f
PM WWW   Вверх
mes
Дата 5.12.2011, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  5.12.2011,  18:17 Найти цитируемый пост)
а разве это не тот случай?

тот случай здесь :
Код

template<typename T1, typename T2>
struct A {};

template<typename...Args>
struct B : A<Args...> {};


Добавлено через 5 минут и 13 секунд
Цитата(boostcoder @  5.12.2011,  18:17 Найти цитируемый пост)
 я полагал что при использовании std::tuple компилятор будет так же говорить что что-то там не реализовано.

удивительно.. ведь в той нашей многообсуждаемой теме это проскальзовало не раз..  smile 


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


pattern`щик
****


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

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



Цитата(mes @  5.12.2011,  19:22 Найти цитируемый пост)
в той нашей многообсуждаемой теме это проскальзовало не раз

там ведь мы fusion::vector использовали. нет? оО

Добавлено через 12 минут и 59 секунд
ну да. и в fusion::invoke() передавали.
PM WWW   Вверх
mes
Дата 5.12.2011, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  5.12.2011,  19:08 Найти цитируемый пост)
там ведь мы fusion::vector использовали. нет? 

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



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


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(mes @  5.12.2011,  20:22 Найти цитируемый пост)
кстати по теме , там был и пример инвокинга этого тьюпла

этот apply и apply_inner - простые функции, а не методы класса.
Я попробовал переделать
http://liveworkspace.org/code/e7d6dd7ce1e3...c56abd587e04533
но запутался  smile 


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 10.1.2012, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



при создании соседней темы, наткнулся на эту.

Цитата(mes @  4.12.2011,  16:42 Найти цитируемый пост)
не лишний ли в этом ряду ?

что подразумевалось?
PM WWW   Вверх
boostcoder
Дата 16.6.2012, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(mes @ 4.12.2011,  16:26)
Цитата(boostcoder @  4.12.2011,  15:22 Найти цитируемый пост)
boost.fusion::vector 

он с вариадиками же не работает ? или уже начал ?

кстати, то ли это в 4.7.1 пофиксили, то ли в бусте. но оно уже работает!
http://liveworkspace.org/code/1160db3c1c7a...4f1783e35bd6969

PM WWW   Вверх
boostcoder
Дата 16.6.2012, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



теперь изначальную задачу можно решить так:
Код

#include <iostream>

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/container/vector/vector_fwd.hpp>
#include <boost/fusion/include/vector_fwd.hpp>
#include <boost/fusion/algorithm/transformation/push_front.hpp>
#include <boost/fusion/include/push_front.hpp>
#include <boost/fusion/functional/invocation/invoke.hpp>

template < class C, class Res, class ...Args >
struct Delegate {
   Res (C::*m_fun)(Args...);
   C * m_obj;

   boost::fusion::vector<Args...> m_args;

   Delegate( Res (C::*fun)(Args...), C * obj, Args... args )
      :m_fun(fun)
      ,m_obj(obj)
      ,m_args(args...)
   {}

   Res run() {
      return boost::fusion::invoke( m_fun, boost::fusion::push_front( m_args, m_obj ) );
   }
};

template < class C, class Res, class ...Args >
struct Delegate< C, Res, Args... >
delegate( Res (C::*fun)(Args...), C * obj, Args... args ) {
   return Delegate<C, Res, Args...>( fun, obj, args... );
}

struct A {
   int foo( int x, int y ) { return x + y; }
};

int main() {
   A a;
   auto d = delegate( &A::foo, &a, 20, 22 );
   int y = d.run();
   std::cout << y << std::endl;
}

http://liveworkspace.org/code/1507c28023ee...4a49aaaa63b12f2
PM WWW   Вверх
borisbn
Дата 17.6.2012, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



boostcoder, спасибо (+1). Если потребуется в будущем - обязательно воспользуюсь. Жаль только, что всё это не включено в C++11. Так сказать искаропки...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 19.6.2012, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  17.6.2012,  01:02 Найти цитируемый пост)
Жаль только, что всё это не включено в C++11. Так сказать искаропки...

ну вот, только С++11 и почти все искаропки smile 
может кто подскажет как еще упростить?
Код

#include <iostream>
#include <tuple>

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

namespace details {

template<size_t... idxs>
struct index_list {
   typedef index_list<idxs..., sizeof...(idxs)> next;
};

template<size_t idx>
struct make_index_list {
   typedef typename make_index_list<idx-1>::type::next type;
};

template<>
struct make_index_list<0> {
   typedef index_list<> type;
};

} // ns details

/***************************************************************************/

template<typename C, typename Res, typename... Args>
struct Delegate {
   Res (C::*m_fun)(Args...);
   C * m_obj;

   typedef std::tuple<Args...> args_type;
   args_type m_args;

   Delegate( Res (C::*fun)(Args...), C * obj, Args... args )
      :m_fun(fun)
      ,m_obj(obj)
      ,m_args(args...)
   {}

   Res run() {
      return invoke(
          m_obj
         ,m_fun
         ,m_args
         ,typename details::make_index_list<sizeof...(Args)>::type()
      );
   }

private:
   template<typename F, size_t... indexes>
   Res invoke(C* obj, F func, args_type& args, details::index_list<indexes...>) {
      return (obj->*func)(std::forward<Args>(std::get<indexes>(args))...);
   }
};

/***************************************************************************/

template<typename C, typename Res, typename...Args >
struct Delegate< C, Res, Args... >
make_delegate( Res (C::*fun)(Args...), C * obj, Args... args ) {
   return Delegate<C, Res, Args...>( fun, obj, args... );
}

/***************************************************************************/
/***************************************************************************/
/***************************************************************************/

struct A {
   int foo( int x, int y ) { return x + y; }
};

/***************************************************************************/

int main() {
   A a;
   auto d = make_delegate( &A::foo, &a, 20, 22 );
   int y = d.run();
   std::cout << y << std::endl;
}

/***************************************************************************/

http://liveworkspace.org/code/b3688804be3d...9d99fb5f9a7028e
PM WWW   Вверх
borisbn
Дата 20.6.2012, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(boostcoder @  19.6.2012,  18:14 Найти цитируемый пост)
ну вот, только С++11 и почти все искаропки

Спасибо. С сотенной репой тебя


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 20.6.2012, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  20.6.2012,  09:35 Найти цитируемый пост)
С сотенной репой тебя

не в этом цель была.
просто любопытство =)

PM 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.1689 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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