![]() |
![]() ![]() ![]() ![]() |
![]() |
Boost.Assignment DocumentationBoost , ,
|
||||||||||||||||||||||||||||||||||||||
| Header | Includes |
|---|---|
| все, кроме поддержки контейнеров | |
list_of(),map_list_of(),tuple_list_of(),ref_list_of()иcref_list_of() | |
оператор +=()для всех стандартных контейнеров (см. ниже) | |
оператор +=()дляstd::deque, | |
оператор +=()дляstd::list, | |
оператор +=()дляstd::mapиstd::multimap, | |
оператор +=()дляstd::queueиstd::priority_queue, | |
оператор +=()дляstd::setиstd::multiset, | |
оператор +=()дляstd::slist, если класс доступен, | |
оператор +=()дляstd::stack, | |
оператор +=()дляstd::vector, | |
Классприсваивание_исключение, которое может быть выброшено прокси, возвращеннымlist_of() | |
Функцииmake_list_inserter(),push_back(),push_front(),insert(),push()и classlist_inserter, который является основой всей этой библиотеки. | |
Функцииptr_push_back(),ptr_push_front()иptr_insert() | |
Функцииptr_map_insert() | |
Function ptr_list_of()
|
В следующих трех точках (...) будет означать, что реализация определена.оператор +=()возвращает прокси, который пересылает вызовы либоpush_back(),insert(), либоpush()в зависимости от того, какую работу поддерживает контейнер.
list_inserterstackccvvvvvv;][23 Эти две функции используются для построения анонимного списка, который может быть преобразован в любой стандартный контейнер ибустер::массивОбъект, возвращаемый двумя функциями, гарантированно имеет интерфейс, описанный ниже.
namespace boost { namespace assign { template< class T > class Implementation-defined { public: const_iterator begin() const; const_iterator end() const; template< class U > Implementation-defined& operator,( U u ); // inserts default-constructed object Implementation-defined& operator()(); template< class U > Implementation-defined& operator()( U u ); template< class U, class U2 > Implementation-defined& operator()( U u, U2 u2 ); // // and similarly up to 5 arguments // // // Convert to a 'Container'. 'Container' must have a constructor // which takes two iterators. // template< class Container > operator Container() const; // // Convert to a container adapter like 'std::stack<>'. // Convertible-to-adapter to_adapter() const; // // // Convert to eg. 'boost::array<T,std::size_t>'. If the // assigned variable is too small, // a assignment_exception is thrown. // If the assigned variable it is too big, the rest of the // values are default-constructed. // template< template <class,std::size_t> class Array, class U, std::size_t sz > operator Array<U,sz>() const; }; // // Comparison operators. 'op' can be <,>,<=,>=,==,!= // template< class Range > bool op( const Implementation-defined&, const Range& ); template< class Range > bool op( const Range&, const Implementation-defined& ); template< class T > Implementation-defined list_of(); template< class T > Implementation-defined list_of( T t ); template< class T, class U, class U2 > Implementation-defined list_of( U u, U2 u2 ); template< class T, class U, class U2, class U3 > Implementation-defined list_of( U u, U2 u2, U3 u3 ); template< class T, class U, class U2, class U3, class U4 > Implementation-defined list_of( U u, U2 u2, U3 u3, U4 u4 ); template< class T, class U, class U2, class U3, class U4, class U5 > Implementation-defined list_of( U u, U2 u2, U3 u3, U4 u4, U5 u5 ); template< class Key, class T > Implementation-defined map_list_of( Key k, T t ) { return list_of< std::pair<Key,T> >()( k, t ); } } // namespace 'assign' } // namespace 'boost'
repeat(),
repeat_fun() and range() Эти первые две функции существуют как самостоятельные функции, так и функции-члены объекта, возвращаемогоlist_of()иlist_inserter. Свободно стоящие версии используются для создания крючка для оператора,, чтобы мы могли вызывать функции в середине списка запятых. Функции-члены используются, когда нам нужно назвать функции в середине списка скобок. В обоих случаях мы имеем, что
повтора()является(std::size_t,T), иповтора_fun()является(std::size_t,Nullary_function)
The function range() only exists as a member function. The following two overloads are provided:
template< class SinglePassIterator > Implementation-defined range( SinglePassIterator first, SinglePassIterator last ); template< class SinglePassRange > Implementation-defined range( const SinglePassRange& rng );
list_inserterСинопсис
namespace boost { namespace assign { template< Function, Argument = void > class list_inserter { Function fun; public: explicit list_inserter( Function fun ); // conversion constructor template< class Function2, class Arg > list_inserter( const list_inserter<Function2,Arg>& ); public: template< class U > list_inserter& operator,( U u ); template< class U > list_inserter& operator=( U u ); // calls 'fun()' with default-constructed object list_inserter& operator()(); template< class U > list_inserter& operator()( U u ); template< class U, class U2 > list_inserter& operator()( U u, U2 u2 ) { // // if 'Argument' is 'void' // fun( u, u2 ); // else // fun( Argument( u, u2 ) ); // return *this; } // // similarly up to 5 arguments // }; template< class C > list_inserter< ... > push_back( C& ); template< class C > list_inserter< ... > push_front( C& ); template< class C > list_inserter< ... > insert( C& ); template< class C > list_inserter< ... > push( C& ); } // namespace 'assign' } // namespace 'boost'
Обратите внимание, как аргументы оператору,иоператорупередаются по-разномувесельюв зависимости от типаАргумента. Поэтому, если мы передаем только один шаблонный аргументlist_inserter,мы можем перенаправить «произвольные» списки аргументов функций. Если мы передаем два аргумента шаблонаlist_inserter, мы можем строить типы с помощью «произвольных» конструкторов.
И поскольку ссылка наlist_inserterвозвращается, мы можем объединить список аргументов очень эффективным способом.
make_list_inserter()Простая «конструкторская» функция дляlist_inserter. Типичное использование этой функции состоит в том, чтобы назвать ее результатомповышения::bind(), который в целом возвращает нечитаемый и странный шаблон класса.
namespace boost { namespace assign { template< class Function > list_inserter<Function> make_list_inserter( Function fun ) { return list_inserter<Function>( fun ); } } }
Эта библиотека использует библиотеку препроцессоров для реализации перегруженных версий оператора()()иlist_of(). По умолчанию вы можете назвать эти функции пятью аргументами, но вы также можете настроить это число, определив заголовок из этой библиотеки:
#defineBOOST_ASSIGN_MAX_PARAMS10#include<boost/assignhpp>
Гарантии исключения библиотекой являются такими же, как и гарантии функции, которая передается. Для стандартных контейнеров это означает, что сильная гарантия предоставляется для одной вставки и что базовая гарантия предоставляется для многих вставок (при условии, что копируемый объект дает базовую гарантию).
Функции могут включать стандартные исключения, такие какstd::bad_alloc. Обратите внимание, однако, что, к сожалению, стандарт не гарантирует отказы в распределении в стандартных контейнерах, о которых будет сообщеноstd::bad_allocили исключения, полученные изstd:: Exception.
assignment_exceptionИсключение бросается оператором преобразования в прокси-объекте, возвращенном из списка.
namespace boost { namespace assign { class assignment_exception : public std::exception { public: explicit assignment_exception( const char* what ); virtual const char* what() const throw(); }; } }
Очень просто заставить библиотеку работать с новыми классами. Этот код показывает, как использоватьоператор +с контейнером:
Обратите внимание, что мы передаем второй аргумент шаблонаlist_inserter, поэтому списки аргументов будут использоваться для построения объектаV. В противном случае мы могли бы попытаться вызватьpush_back()аргументамиnвместо одного.Альтернативным способом было бы использовать
бустер::функцияибустер::бинд()в комбинации. Однако в этом случае нужно помнить, что незаконно брать адрес функции в стандартной библиотеке.Вызов функции с большим количеством аргументов также может быть очень полезным. Этот небольшой пример показывает, как мы используем эту функциональность:
The full example can be seen in email_example.cpp// // A class representing emails // class email { public: enum address_option { check_addr_book, dont_check_addr_book }; private: typedef std::map< std::string,address_option > address_map; // // Store list of persons that must be cc'ed // mutable address_map cc_list; // // This extra function-object will take care of the // insertion for us. It stores a reference to a // map and 'operator()()' does the work. // struct add_to_map { address_map& m; add_to_map( address_map& m ) : m(m) {} void operator()( const std::string& name, address_option ao ) { m[ name ] = ao; } }; public: // // This function constructs the appropriate 'list_inserter'. // Again we could have use 'boost::function', but it is // trivial to use a function object. // // Notice that we do not specify an extra template // parameter to 'list_inserter'; this means we forward // all parameters directly to the function without // calling any constructor. // list_inserter< add_to_map > add_cc( std::string name, address_option ao ) { // // Notice how we pass the arguments 'name' and 'ao' to // the 'list_inserter'. // return make_list_inserter( add_to_map( cc_list ) )( name, ao ); } }; // // Now we can use the class like this: // email e; e.add_cc( "Mr. Foo", email::dont_check_addr_book ) ( "Mr. Bar", email::check_addr_book ) ( "Mrs. FooBar", email::check_addr_book );
Examples
Дополнительные примеры можно найти в тестовых файлах:
- email_example.cpp
- my_vector_example.cpp
- multi_index_container.cpp
- array.cpp
- list_of.cpp
- std.cpp
- list_inserter.cpp
- list_of_work_around.cpp
Supported libraries
Here is a list libraries has been tested with Boost.Assign:
boost::arrayboost::multi_index_containerBoost.Pointer Container
Portability
Библиотека была успешно составлена и протестирована с помощью MVC++ 7.1, GCC 3.2 (под Cygwin) Comeau 4.3.3
Существуют ограничения на платформы, не поддерживающие шаблонные операторы преобразования. Решение состоит в том, чтобы вызвать определенные функции члена на объекте, возвращенном
list_of():{ using namespace std; using namespace boost; using namespace boost::assign; vector<int> v = list_of(1)(2)(3)(4).to_container( v ); set<int> s = list_of(1)(2)(3)(4).to_container( s ); map<int,int> m = map_list_of(1,2)(2,3).to_container( m ); stack<int> st = list_of(1)(2)(3)(4).to_adapter( st ); queue<int> q = list_of(1)(2)(3)(4).to_adapter( q ); array<int,4> a = list_of(1)(2)(3)(4).to_array( a ); }Обратите внимание, как вы должны предоставить функции с аргументом, чтобы можно было вывести правильный тип возврата.
Некоторые стандартные библиотеки также не работают. Одна проблема заключается в том, что
вставка()может не работать:Решение заключается в использованиикарта<int,int>следующая;вставкаследующая]1,22,3// ошибка компиляцииmap_list_of()вместо:.<int,int>следующая=1,22,3
History and Acknowledgment
Идея создания библиотеки назначения/инициализации не нова. Функциональность этой библиотеки очень напоминает библиотеку инициализации контейнеров STL Леора Золмана, но для достижения своих целей она не полагается на анализ строк.
Библиотека ненавязчива и предъявляет только минимальные требования к своим поддерживаемым классам. Перегрузка оператора запятой иногда рассматривается как плохая практика.. Тем не менее, это было сделано с успехом, например, в Библиотеке вычислений генеративной матрицы и Блице для инициализации матриц (см.).и
. Библиотека инициализации перегружает оператора запятой безопасным способом, позволяя функциям свободного стояния возвращать объект, который отвечает за инициализацию. Поэтому требуется явное действие от программиста, чтобы начать использовать перегруженного оператора,.В последнее время ведутся некоторые дискуссии о совершенствовании языка для поддержки лучшей инициализации (см.)..
Особая благодарность
- Леор Золман для нашей многократной дискуссии, которая в итоге привела к этой библиотеке.
- Том Бринкман — менеджер по обзорам.
- Хоакин Муньос для переносимости vc6/vc7.
- Павел Возенилек за его бесчисленные предложения, улучшения и исправления переносимости.
- Рене Ривера для переносимости Code Warrior.
References
- Скотт Мейерс, More Effective C++, Item 7, Addison Wesley, 1996
- K. Czarnecki and U.W. Eisenecker, "Generative programming", Addison-Wesley, 2000
- http://www.oonumerics.org/blitz/
- Gabriel Dos Reis and Bjarne Stroustrup,"Generalized Initializer Lists", 2003
Авторское право Thorsten Ottosen 2003-2006
Статья Boost.Assignment Documentation раздела может быть полезна для разработчиков на c++ и boost.
:: Главная :: ::
реклама