Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > подскажите с реализацией функции.


Автор: boostcoder 26.5.2011, 07:48
всем доброго дня.

нужно понять, какой должна быть декларация/реализация функции, позволяющая использовать ее так:
Код

func({"tag", value}, {"tag2", value2});

т.е. кол-во аргументов должно быть variadic. в данном случае аргументов два.
тип аргумента({"tag", value}) - допустим std::pair<std::string, T>, где Т - шаблонный параметр.

я так полагаю, что тут нужно использовать initializer_list.
все. дальше мысли не идут.

спасибо.

Up.
по моему, как-то криво объяснил...
в общем, сейчас делаю так:
Код

json_props props; // json_props - тип, содержащий список пар.
props.add_prop(
   "prop_name1",
   prop_value1
);
props.add_prop(
   "prop_name2",
   prop_value2
);

net_query(client, props);

prop_name - всегда строка.
prop_value - значения произвольных типов.

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

вот smile

Автор: mes 26.5.2011, 08:37
Цитата(boostcoder @  26.5.2011,  06:48 Найти цитируемый пост)
позволяющая использовать ее так:

если добавить еще пару фигурных скобок, то можно сделать с initializer_list.

Добавлено через 2 минуты и 44 секунды
как то так :
Код

void fn (std::initializer_list<std::pair<int, std::string> > a ) 
{
   for ( auto it = a.begin(); it != a.end(); ++it)
   { 
       std::cout <<"{"<< it->first << "," << it->second << "} "; 
   } 
}

int main ()
{
   fn ({{ 1, "abc" }, {2, "def"}});
}


Добавлено через 4 минуты и 28 секунд
Цитата(boostcoder @  26.5.2011,  06:48 Найти цитируемый пост)
. нет смысла создавать временный объект

от этого не уйти.. только в одном случае он будет явно  в другом нет.. 




Автор: boostcoder 26.5.2011, 09:13
Цитата(mes @  26.5.2011,  08:37 Найти цитируемый пост)
если добавить еще пару фигурных скобок, то можно сделать с initializer_list.

а как быть со вторым параметром инициализации? его тип может быть произвольным.

как вариант, завести нужное кол-во функций типа:
Код

template<typename T0>
void func(const std::pair<const std::string&, const T0&> arg0) {
}
template<typename T0, typename T1>
void func(const std::pair<const std::string&, const T0&>& arg0, const std::pair<const std::string&, const T1&>& arg1) {
}


вот только что-то я накосячил... и не пойму что не так.. smile 
http://liveworkspace.org/code/d4eb112c5c90912138a232223107a171

Добавлено через 1 минуту и 5 секунд
Цитата(mes @  26.5.2011,  08:37 Найти цитируемый пост)
только в одном случае он будет явно.  в другом нет

это понятно. это и имел ввиду.

Автор: mes 26.5.2011, 09:52
Цитата(boostcoder @  26.5.2011,  08:13 Найти цитируемый пост)
 его тип может быть произвольным.

не понятно, Вам нужно получить в итоге кортеж или массив ?

Автор: boostcoder 26.5.2011, 10:02
Цитата(mes @  26.5.2011,  09:52 Найти цитируемый пост)
Вам нужно получить в итоге кортеж или массив

массив pair`ов, где first - std::string, а second - произвольный тип.
 вот smile

Автор: mes 26.5.2011, 10:25
Цитата(boostcoder @  26.5.2011,  09:02 Найти цитируемый пост)
массив pair`ов, где first - std::string, а second - произвольный тип.

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

Автор: boostcoder 26.5.2011, 10:28
Цитата(boostcoder @  26.5.2011,  10:02 Найти цитируемый пост)
массив pair`ов

хотя нет.
можно чего-то типа:
Код

template<typename T>
struct mypair {
   std::string name;
   const T& value;
};


Цитата(mes @  26.5.2011,  10:25 Найти цитируемый пост)
массив может быть только однородным

это понятно. потому и ломаю голову..

Автор: baldina 26.5.2011, 10:29
раз json, то достаточно строк

Автор: mes 26.5.2011, 10:31
Цитата(boostcoder @  26.5.2011,  09:28 Найти цитируемый пост)
это понятно. потому и ломаю голову.. 

ну так что должно будет потом получиться из произвольного типа ?  что от него ожидается ?

Автор: boostcoder 26.5.2011, 10:31
Цитата(baldina @  26.5.2011,  10:29 Найти цитируемый пост)
раз json, то достаточно строк 

нет.
раз json, то нужно сериализовать пользовательские типы и формировать json.
но спасибо.

Добавлено через 2 минуты и 12 секунд
Цитата(mes @  26.5.2011,  10:31 Найти цитируемый пост)
ну так что должно будет потом получиться из произвольного типа ?  что от него ожидается ?

ну вот, допустим, при помощи initializer_list, инициализировать аргументы в соответствии с:
Код

func({"tag", value}, {"tag2", value2});

а внутри func() сериализовать их и сформировать json-структуру.

Автор: mes 26.5.2011, 10:55
Цитата(boostcoder @  26.5.2011,  09:31 Найти цитируемый пост)
ри помощи initializer_list, инициализировать аргументы в соответствии с:

еще раз... initializer_list массив, а не кортеж..  приводить аргументы надо до попадания в него, а не после ..

Добавлено через 44 секунды
P.S. вспомните про (шаблонный) конструктор.. 

Автор: baldina 26.5.2011, 11:00
Цитата(boostcoder @  26.5.2011,  10:31 Найти цитируемый пост)
нет.
раз json, то нужно сериализовать пользовательские типы и формировать json.

можно разделить уровни - где кончаются пользовательские типы и начинается json
если хочется типов, лучше явного добавления параметров в запрос не придумать
если хочется простоты типа javascript/php, придется поступиться типами
тут еще дело в том, что программа, формирующая json запрос понятия не имеет, какие _должны_ быть типы, так что все сводится к корректному преобразованию из пользовательского типа в строку

Добавлено через 37 секунд
Цитата(mes @  26.5.2011,  10:55 Найти цитируемый пост)
приводить аргументы надо до попадания в него, а не после ..

 smile

Добавлено через 2 минуты и 42 секунды
хорошей идеей мне кажется использования что-то типа boost::variant

Автор: boostcoder 26.5.2011, 11:07
Цитата(mes @  26.5.2011,  10:55 Найти цитируемый пост)
 initializer_list массив, а не кортеж

да, знаю. это я как пример привел.

Цитата(mes @  26.5.2011,  10:55 Найти цитируемый пост)
вспомните про (шаблонный) конструктор

так получается, что это единственный способ.. ок.
http://liveworkspace.org/code/7f4928a72ee94fc31f4c35768df4a0eb

остался второй вопрос:
Цитата(boostcoder @  26.5.2011,  07:48 Найти цитируемый пост)
кол-во аргументов должно быть variadic.


variadic-templates тут не поможет: http://liveworkspace.org/code/67bc8166f42f6f446c39f37e81ad30e5
что, тупо написать 10 функций(у меня минимум 3 значения и максимум 13) для нужного кол-ва аргументов?

Добавлено @ 11:09
Цитата(baldina @  26.5.2011,  11:00 Найти цитируемый пост)
можно разделить уровни - где кончаются пользовательские типы и начинается json

именно от этого и хочу избавиться.

Цитата(baldina @  26.5.2011,  11:00 Найти цитируемый пост)
если хочется типов, лучше явного добавления параметров в запрос не придумать

почему?

Цитата(baldina @  26.5.2011,  11:00 Найти цитируемый пост)
если хочется простоты типа javascript/php, придется поступиться типами

почему?

Цитата(baldina @  26.5.2011,  11:00 Найти цитируемый пост)
тут еще дело в том, что программа, формирующая json запрос понятия не имеет, какие _должны_ быть типы

почему?

зы
ух сколько вопросов smile

Добавлено @ 11:12
Цитата(baldina @  26.5.2011,  11:00 Найти цитируемый пост)
хорошей идеей мне кажется использования что-то типа boost::variant

а вот этого не надо.
мне нужна информация о типе.
и как показано в первом посте - у меня работает. понимает что за тип. и формирует значение соответствующего типа(строка/double/массив) smile 

Автор: baldina 26.5.2011, 11:20
boostcoder, Вы не поняли.
прочитайте еще раз и подумайте

Автор: boostcoder 26.5.2011, 11:21
Цитата(boostcoder @  26.5.2011,  11:07 Найти цитируемый пост)
формирует значение соответствующего типа(строка/double/массив)

если массив - идем в рекурсию. и получается прям как это: http://en.wikipedia.org/wiki/Json#Data_types.2C_syntax_and_example
и никакого рукоблудства smile

Добавлено через 1 минуту и 29 секунд
Цитата(baldina @  26.5.2011,  11:20 Найти цитируемый пост)
Вы не поняли

то, что я не понял, я как раз и понял. потому столько вопросов задал.

Автор: baldina 26.5.2011, 11:23
вот смотрите:

Код

add_prop(
   "prop_name2",
   prop_value2
);


prop_value2 может принимать значения типа из некоторого набора типов. со значением "prop_name2" этот тип не связан. так что если у вас variant из того самого набора, то ничего не меняется.
если же Вы захотите связать имя свойства и тип (что имхо излишне), это совсем другая история и архитектура

Добавлено через 3 минуты и 33 секунды
Цитата(baldina @  26.5.2011,  11:23 Найти цитируемый пост)
со значением "prop_name2" этот тип не связан

именно поэтому вся задача сводится к преобразованию типов в строки (сериализация), но не к проверке типов

Добавлено через 7 минут и 33 секунды
вообще, чувствуется желание задать параметры JSON естественным образом, синтаксически наиболее близким к javascript
это можно сделать, перегружая операции (примерно как делается грамматика в boost::spirit)

Автор: boostcoder 26.5.2011, 11:33
baldina, не понимаю что Вы хотите сказать..

из таких операций:
Код

int iv = 33;
double dv = 3.14159265;
std::string sv = "string value";
std::vector<std::string> sa = {"value1", "value2", "value3"};

add_prop(
   "name1",
   iv
);
add_prop(
   "name2",
   dv
);
add_prop(
   "name3",
   sv
);
add_prop(
   "name4",
   sa
);

получаю это:
Код

{
   "name1": 33,
   "name2": "3.14159265",
   "name3": "string value",
   "name4": [
      "value1",
      "value2",
      "value3"
   ]
}


как Вы предлагаете такого добиться, не имея информации о типе?

Добавлено через 1 минуту и 32 секунды
Цитата(baldina @  26.5.2011,  11:23 Найти цитируемый пост)
именно поэтому вся задача сводится к преобразованию типов в строки (сериализация), но не к проверке типов

та я не проверяю типы!
информация о типе мне нужна для того, чтоб соответствующим образом сформировать json-запись для этого типа!
 smile

Добавлено через 1 минуту и 52 секунды
вопрос закрыт.
всем спасибо.

Автор: mes 26.5.2011, 11:59
Цитата(boostcoder @  26.5.2011,  10:33 Найти цитируемый пост)
как Вы предлагаете такого добиться, не имея информации о типе?

сделать класс _свойство_, который будет принимать типизированное значение и приводить сразу к строке.. 

Автор: boostcoder 26.5.2011, 12:04
Цитата(mes @  26.5.2011,  11:59 Найти цитируемый пост)
сделать класс _свойство_, который будет принимать типизированное значение и приводить сразу к строке..

у меня так и происходит. только в методе add_prop()
но я хочу избавиться от ручного кода и явного временного объекта. поэтому перенес в конструктор: http://liveworkspace.org/code/7f4928a72ee94fc31f4c35768df4a0eb
теперь осталось понять каким образом написать функцию принимающую 3-13 аргументов... наверное придется написать 10 функций. ничего иного в голову не приходит..

Добавлено через 9 минут и 19 секунд
в общем получилось как и хотел smile
Код

func({"arg0", i});

func(
   {"arg0", i},
   {"arg1", d}
);

func(
   {"arg0", i},
   {"arg1", d},
   {"arg2", "val"}
);


Автор: mes 26.5.2011, 12:24
Цитата(boostcoder @  26.5.2011,  11:04 Найти цитируемый пост)
теперь осталось понять каким образом написать функцию принимающую 3-13 аргументов... наверное придется написать 10 функций. ничего иного в голову не приходит..


не пойму, может сегодня магнитная буря ?..  

делайте класс пары, который шаблонным конструктором принимает нужные аргументы и приводит их к строковому виду..
так как делает это add_prop.. а после применяете список инициализации.. 

Автор: boostcoder 26.5.2011, 12:30
Цитата(mes @  26.5.2011,  12:24 Найти цитируемый пост)
может сегодня магнитная буря ?

возможно smile

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

func({"arg0", i});
func(
   {"arg0", i},
   {"arg1", d}
);
func(
   {"arg0", i},
   {"arg1", d},
   {"arg2", "val"}
);

http://liveworkspace.org/?id=cb7718bf15abd392498b2e2f499ef0c5

Автор: mes 26.5.2011, 12:50
Цитата(boostcoder @  26.5.2011,  11:30 Найти цитируемый пост)
а в том, как реализовать функцию принимающую произвольное кол-во моих пар.

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

http://liveworkspace.org/code/13b4276480f9f0e6ac9bdf2e5e4698ca

Автор: boostcoder 26.5.2011, 12:53
Цитата(mes @  26.5.2011,  12:50 Найти цитируемый пост)
вот например

ааа..
теперь понял.
я как-то не подумал о том, что можно завернуть initializer_list в initializer_list. буду знать.

спасибо огромное.
так подходит.

вопрос закрыт...вроде как..

Автор: boostcoder 29.5.2011, 05:21
mes, такой еще вопрос:
Код

#include <iostream>
#include <string>

#include <boost/fusion/support/pair.hpp>
#include <boost/fusion/include/pair.hpp>

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

int main() {
   
   // хочу инициализировать произвольное кол-во fusion::pair
   // мне не известно ни кол-во pair` ов, ни типы для них
   func<
      <int, int>, // first-second
      <char, double> // first-second
   >();
}

http://liveworkspace.org/code/0299c51fad60bd849a343a60d1325cdb

Автор: mes 30.5.2011, 08:14
Цитата

   // хочу инициализировать произвольное кол-во fusion::pair
   // мне не известно ни кол-во pair` ов, ни типы для них

абсолютно не понятно, что Вы пытаетесь спросить..
 smile 

Автор: boostcoder 30.5.2011, 11:16
кажется понял..
проверю и отпишусь.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)