четверг, 5 февраля 2009 г.

Boost.Assign

Может тема и известна обширно, но не могу не поделиться радостями использования библиотеки Boost.Assign.
Дело в том, что в стандарте С++ не предусмотрено (пока, ждем С++0x) удобное заполнение контейнеров объектами. Как массивы можно заполнять структуры (и то не все):
struct object
{
long value;
};

object data[] = { 10, 20, 30 };

Но если нужно заполнить динамический контейнер как std::vector<> то этот метод здесь не применим. Как раз тут идет на помощь Boost. С помощью нехитрой библиотеки Assign можно делать такое:
std::vector<long> data;
data += 10, 20, 30;

и даже
std::vector<long> v;
std::vector<long> data;
data += repeat(5, 10), repeat(5, 20), range(v.begin(),v.end());

или
std::map<std::string, int> months;  
insert(months)
( "january", 31 )( "february", 28 )
( "march", 31 )( "april", 30 )
( "may", 31 )( "june", 30 )
( "july", 31 )( "august", 31 )
( "september", 30 )( "october", 31 )
( "november", 30 )( "december", 31 );

Когда в проект было не вставить Boost, пришлось сделать нечто подобное, что отлично работало. Я правда добавил побольше генераторов - генерация случайных чисел и вставка сразу в контейнер, генерация последовательностей. Экономит время написания кода, особенно когда нужно забивать векторы отладочными данными, да и визуально виглядит очень читабельно. Использую давно - проблем не было, и всем рекомендую.

В принципе методы использованые в библиотеки могут оказаться полезными и для других нужд. К примеру, существует ядро, которое возвращает объект, а объект в свою очередь имеет контейнер значений который мы хотим заполнить:
DB db;
Object obj = db.get("object");
obj.push_back(10);
obj.push_back(11);
obj.push_back(12);

а можно возвращать промежуточный объект, который в случае чего может быть приведен к объекту Object, и в котором будут переопределены операторы += и , добавляющие данные в объект:
DB db;
db.get("object") += 10, 11, 12;

Это как пример, иногда всеже предпочтительнее первый вариант.

Комментариев нет:

Отправить комментарий