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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> variadic templates и "разворот" в типы посредники 
V
    Опции темы
boostcoder
Дата 10.1.2012, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



всем привет.

к примеру, имеется у нас следующая функция:
Код

template<typename... Args>
void func(const Args&... args) {}

используем мы ее как обычно:
Код

func(1);
func(1,2);

тут проблем нет.

теперь давайте представим, что эта функция на самом деле декларирована так:
Код

void func(ArgWrapper a0 = ArgWrapper(0,0), ArgWrapper a1 = ArgWrapper(0,0), ArgWrapper a2 = ArgWrapper(0,0), и т.д....) {}

а мы хотим ее использовать так:
Код

struct type {
   template<typename... Args>
   static void method(const Args&... args) {
      func(args...); // тут как записать?
   }
};


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

в общем, последний пример, для ясности должен компилятором генерироваться так:
Код

struct type {
   template<typename... Args>
   static void method(const Args&... args) {
      func(
         ArgWrapper(typeid(args[0]).name(), args[0]),
         ArgWrapper(typeid(args[1]).name(), args[1]),
         ArgWrapper(typeid(args[2]).name(), args[2])
      );
   }
};


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


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


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

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



проблема пройтись по списку ? рекурсия в помощь..
как обернуть отдельный тип полагаю вопросов не возникает.. 



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


pattern`щик
****


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

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



оказалось все сильно проще. просто нужно больше времени уделять чтению доки.
Код

#include <typeinfo>
#include <iostream>

struct ArgWrapper {
   ArgWrapper(const char* name, const void* data)
      :name(name)
      ,data(data)
   {}
   
   const char* name;
   const void* data;
};

struct invoker {
   static void func(ArgWrapper a0 = ArgWrapper("",""),
                    ArgWrapper a1 = ArgWrapper("",""),
                    ArgWrapper a2 = ArgWrapper("",""))
   {
      std::cout
      << "a0: name = " << a0.name << ", data = " << a0.data << std::endl
      << "a1: name = " << a1.name << ", data = " << a1.data << std::endl
      << "a2: name = " << a2.name << ", data = " << a2.data << std::endl;
   }
};

struct type {
   template<typename... Args>
   void method(const Args&... args) {
      invoker::func(ArgWrapper(typeid(Args).name(), &args)...); // <<<<<<<<<<<<<<<<<<<<<<<<<<
   }
};

int main() {
   type t;
   t.method(1);
   std::cout << "ping 1" << std::endl;
   t.method(1, 2.9);
   std::cout << "ping 2" << std::endl;
   t.method(.1, 2, .14159);
   std::cout << "ping 3" << std::endl;
}


http://liveworkspace.org/code/bcd126457d6b...dddac6e8f4fe874
я не знал что при "развороте" вариадика, может так же развернуться все выражение в котором вариадик используется smile 
это многое упрощает и в моих прошлых задачах!

всем спасибо.

зы

mes, не могли бы Вы пояснить такой момент.
почему злополучную строку я не могу записать так?: invoker::func({typeid(Args).name(), &args}...);
вроде как это валидная запись.. но компилятор говорит:
Цитата

source.cpp:29:52: error: no matching function for call to 'invoker::func(<brace-enclosed initializer list>&)'
source.cpp:29:52: note: candidate is:
source.cpp:15:16: note: static void invoker::func(ArgWrapper, ArgWrapper, ArgWrapper)
source.cpp:15:16: note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'ArgWrapper'


Это сообщение отредактировал(а) boostcoder - 11.1.2012, 18:47
PM WWW   Вверх
mes
Дата 11.1.2012, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  11.1.2012,  17:41 Найти цитируемый пост)
я не знал что при "развороте" вариадика, может так же развернуться все выражение в котором вариадик используется 

 smile 

Цитата(boostcoder @  11.1.2012,  17:41 Найти цитируемый пост)
 просто нужно больше времени уделять чтению доки.

поделитесь  плиз докой, где такое нашли 
 smile 

Цитата(boostcoder @  11.1.2012,  17:41 Найти цитируемый пост)
у я не могу записать так?:

не знаю, мож в той доке написано ?



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


pattern`щик
****


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

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



mes, по правде говоря, мне подсказали это решение.
но сейчас, полазав по гуглу, я действительно нашел упоминание (вскользь) о такой возможности:
http://www.open-std.org/jtc1/sc22/wg21/doc.../2006/n2080.pdf
глава "2.5 Is the Meta-Operator '...' Necessary?"

http://www.generic-programming.org/~dgrego...-templates.html
в самом начале, в примере:
Код

template<typename... Mixins>
struct myclass : public Mixins... /*наследование от вариадик списка предков!*/ {
  myclass(const Mixins&... mixins)
    : Mixins(mixins)... { } // <<<<<<<<<<<<<<<
};


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

Добавлено через 9 минут и 42 секунды
еще тут большой кусок доки с примерами:
http://publib.boulder.ibm.com/infocenter/l..._templates.html

Добавлено через 13 минут и 8 секунд
и здесь, в первом ответе используется такой же трюк:
http://stackoverflow.com/questions/7381805...iadic-templates
Код

template<int... Indices>
struct indices {
    typedef indices<Indices..., sizeof...(Indices)> next;
};

template<int N>
struct build_indices {
    typedef typename build_indices<N - 1>::type::next type;
};

template<>
struct build_indices<0> {
    typedef indices<> type;
};

// No need to be variadic on the tuple elements as we don't care about them
// So I'm using perfect forwarding for the tuple
template<typename Tuple, int... Indices>
void
do_something_by_index(Tuple&& tuple, int index, indices<Indices...>)
{
    using std::get;

    typedef void (*element_type)(Tuple&&);
    static constexpr element_type table[] = {
        [](Tuple&& tuple)
        { get<Indices>(std::forward<Tuple>(tuple)).DoSomething(); }
        ... // <<<<<<<<<<<<<<<<<<<<<< а выглядит как незаконченная мысль :)
    };

    table[index](std::forward<Tuple>(tuple));
}

// Proverbial layer of indirection to get the indices
template<typename Tuple>
void
do_something_by_index(Tuple&& tuple, int index)
{
    typedef typename std::decay<Tuple>::type decay_type;
    constexpr auto tuple_size = std::tuple_size<decay_type>::value;
    typedef typename build_indices<tuple_size>::type indices_type;

    do_something_by_index(std::forward<Tuple>(tuple), index, indices_type{});
}


Это сообщение отредактировал(а) boostcoder - 11.1.2012, 21:21
PM WWW   Вверх
mes
Дата 12.1.2012, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



boostcoder, спасибо, никогда раньше не приходилось натыкаться, классная возможность!

Это сообщение отредактировал(а) mes - 14.1.2012, 11:39


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


pattern`щик
****


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

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



та же самая проблема. уже третий день. думал только у меня. ну....или...модеры наказали ;)
PM WWW   Вверх
spyswamp
Дата 12.1.2012, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 7



Оффтоп: +1. Репутацию даже смотреть сейчас нельзя.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
boostcoder
Дата 13.1.2012, 08:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



карму починили.
PM WWW   Вверх
boostcoder
Дата 13.1.2012, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



гы. и на википедии появился этот пример smile
заговор какой-то, чесслово..
http://en.wikipedia.org/wiki/Variadic_templates

Добавлено @ 09:54
Цитата

The ... operator has two roles. When it occurs to the left of the name of a parameter, it declares a parameter pack. By using the parameter pack, user can bind zero or more arguments to the variadic template parameters. Parameter packs can also be used for non-type parameters. By contrast, when the ... operator occurs to the right of a template or function call argument, it unpacks the parameter packs into separate arguments, like the args... in the body of printf below. In practice, the use of ... operator in the code causes that the whole expression that precedes the ... operator, will be repeated for every next argument unpacked from the argument pack, and all these expressions will be separated by a comma.


да и вообще, всю страницу по С++11 сильно обновили: http://en.wikipedia.org/wiki/C%2B%2B11

Это сообщение отредактировал(а) boostcoder - 13.1.2012, 10:03
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0545 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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