2013-08-03 1 views
0

У меня есть кусок кода для отправки данных на удаленной стороне, он действует немного как picojson, например:Обработка переменных данных с помощью оператора <<

server::value::object obj; 
obj["cmd"] = server::value("test"); 
obj["url"] = server::value(url); 
... 
obj["code"] = server::value(std::to_string(code)); 

server::value v(obj); 
client.send_to_server(v.process()); 

Пока есть что-то отправить, там будет такой блок.

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

версия < < оператор будет, как:

Data d << "cmd" << "test" 
     << "url" << url 
     << ... << ... 
     << "code" << code; 
client.send_to_server(d); 

Является ли это хорошая идея сделать это? Как его реализовать?

Спасибо.

+0

Я дам вам hint: 'Data & operator << (Data & data, const std :: string & str);' для строк. –

+1

Я задал тот же вопрос несколько дней назад, посмотрим, [[это решение] (http://stackoverflow.com/questions/17868718/variadic-template-operator) соответствует вашим потребностям.Я тоже планировал писать сериализатор. (: – Rubens

ответ

1

Я написал бы по-другому:

d << add_value("cmd", "test") 
    << add_value("url", url) 
    << add_value(..., ...) 
    << add_value("code", code) 
    ; 

Почему? Это яснее и позволяет лучше контролировать тип.

Таким образом, вы создаете класс, скажем, __add_value_temp который содержит как имя и значение, функцию add_value, которая создает этот класс, и написать < < оператор

Data &operator<<(Data &d, const __add_value_temp &val){ 
    d.add(val.name,val.val); 
    return d; 
} 

еще лучше - вместо __add_value_temp вы можете используйте std::pair и используйте std::make_pair вместо add_value!

Data &operator<<(Data &d, const std::pair<std::string,std::string> &val){ 
    d.add(val.first,val.second); 
    return d; 
} 

... 
Data d; 
d << std::make_pair("cmd", "test") 
    << std::make_pair("url", url) 
    << std::make_pair(..., ...) 
    << std::make_pair("code", code) 
    ; 

(последняя нота: может быть умным, чтобы писать operator<< шаблонные на типах pair, так что вы можете передать вещи по ссылке, и вообще возможно избежать ненужного копирования)

+0

BTW - запись ';' одной строки после помощи при копировании/вставке различных значений, а также позволяет легко комментировать строки (например, последней строки). – rabensky

1

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

Похоже, что подобная идея отлично работает с потоками вывода по простой причине: данные, которые вы помещаете в поток для вывода, обрабатываются равномерно. Все, что вы помещаете в << в качестве аргумента, становится частью вывода, кроме манипуляторов потока, которые контролируют, как должен выводиться вывод.

Ваш API отличается: нечетные элементы обрабатываются иначе, чем четные. Более того, ошибочно отправлять нечетное общее количество операндов. Если по какой-то причине вы забудете поставить строковый код на одну из строк, все значения будут беззвучно становиться кодами на последующих строках. Такой API очень хрупкий, поэтому я настоятельно рекомендую его снова.

Я думаю, что API, который позволяет вашим пользователям добавлять элементы в пары, будет работать лучше. Если ваш компилятор C++ 11 совместимый, вы можете также использовать uniform initialization синтаксис:

Data d = { 
    {"cmd", server::value("test")} 
, {"url", server::value(url)} 
, {"code", server::value(std::to_string(code))} 
}; 
Смежные вопросы