Модераторы: 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   Вверх
Страницы: (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.1491 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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