![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Header <boost/operators.hpp> DocumentationBoost , ,
|
|
||||||
Template | Supplied Operations | Requirements | ||||
---|---|---|---|---|---|---|
<less_than_comparable<T> >< less_than_comparable1<T> > |
<bool operator>(const T&, const T&) >< bool operator<=(const T&, const T&) >< bool operator>=(const T&, const T&) > |
<t < t1 >Возврат кабриолета в< bool >. См.Заказная записка. |
||||
<less_than_comparable<T,
U> >< less_than_comparable2<T, U> > |
<bool operator<=(const T&, const U&) >< bool operator>=(const T&, const U&) >< bool operator>(const U&, const T&) >< bool operator<(const U&, const T&) >< bool operator<=(const U&, const T&) >< bool operator>=(const U&, const T&) > |
<t < u ><t > u >.Возврат кабриолета в< bool >. См.Заказная записка. |
||||
<equality_comparable<T> >< equality_comparable1<T> > |
<bool operator!=(const T&, const T&) > |
<t == t1 >Возврат кабриолета в< bool >. |
||||
<equality_comparable<T,
U> >< equality_comparable2<T, U> > |
<bool operator==(const U&, const T&) >< bool operator!=(const U&, const T&) >< bool operator!=(const T&, const U&) > |
<t == u >Возврат кабриолета в< bool >. |
||||
<addable<T> >< addable1<T> > |
<T operator+(const T&, const T&) > |
<T temp(t); temp += t1 >Возврат кабриолета в< T >.Симметричная нота. |
||||
<addable<T, U> >< addable2<T, U> > |
<T operator+(const T&, const U&) >< T operator+(const U&, const T& ) > |
<T temp(t); temp += u >Возврат кабриолета в< T >.Симметричная нота. |
||||
<subtractable<T> >< subtractable1<T> > |
<T operator-(const T&, const T&) > |
<T temp(t); temp -= t1 >Возврат кабриолета в< T >.Симметричная нота. |
||||
<subtractable<T,
U> >< subtractable2<T, U> > |
<T operator-(const T&, const U&) > |
<T temp(t); temp -= u >.Возврат кабриолета в< T >.Симметричная нота. |
||||
<subtractable2_left<T,
U> > |
<T operator-(const U&, const T&) > |
<T temp(u); temp -= t >Возврат кабриолета в< T >. |
||||
<multipliable<T> >< multipliable1<T> > |
<T operator*(const T&, const T&) > |
<T temp(t); temp *= t1 >Возврат кабриолета в< T >.Симметричная нота. |
||||
<multipliable<T,
U> >< multipliable2<T, U> > |
<T operator*(const T&, const U&) >< T operator*(const U&, const T&) > |
<T temp(t); temp *= u >Возврат кабриолета в< T >.Симметричная нота. |
||||
<dividable<T> >< dividable1<T> > |
<T operator/(const T&, const T&) > |
<T temp(t); temp /= t1 >Возврат кабриолета в< T >.Симметричная нота. |
||||
<dividable<T, U> >< dividable2<T, U> > |
<T operator/(const T&, const U&) > |
<T temp(t); temp /= u >Возврат кабриолета в< T >. См. симметричную ноту. |
||||
<dividable2_left<T,
U> > |
<T operator/(const U&, const T&) > |
<T temp(u); temp /= t >.Возврат кабриолета в< T >. |
||||
<modable<T> >< modable1<T> > |
<T operator%(const T&, const T&) > |
<T temp(t); temp %= t1 >Возврат кабриолета в< T >. См. примечание к симметрии. |
||||
<modable<T, U> >< modable2<T, U> > |
<T operator%(const T&, const U&) > |
<T temp(t); temp %= u >Возврат кабриолета в< T >. См. примечание к симметрии. |
||||
<modable2_left<T,
U> > |
<T operator%(const U&, const T&) > |
<T temp(u); temp %= t >Возврат кабриолета в< T >. |
||||
<orable<T> >< orable1<T> > |
<T operator|(const T&, const T&) > |
<T temp(t); temp |= t1 >.Возврат кабриолета в< T >.Симметричная нота. |
||||
<orable<T, U> >< orable2<T, U> > |
<T operator|(const T&, const U&) >< T operator|(const U&, const T&) > |
<T temp(t); temp |= u >Возврат кабриолета в< T >.Симметричная нота. |
||||
<andable<T> >< andable1<T> > |
<T operator&(const T&, const T&) > |
<T temp(t); temp &= t1 >.Возврат кабриолета в< T >.Симметричная нота. |
||||
<andable<T, U> >< andable2<T, U> > |
<T operator&(const T&, const U&) >< T operator&(const U&, const T&) > |
<T temp(t); temp &= u >Возврат кабриолета в< T >.Симметричная нота. |
||||
<xorable<T> >< xorable1<T> > |
<T operator^(const T&, const T&) > |
<T temp(t); temp ^= t1 >.Возврат кабриолета в< T >.Симметричная нота. |
||||
<xorable<T, U> >< xorable2<T, U> > |
<T operator^(const T&, const U&) >< T operator^(const U&, const T&) > |
<T temp(t); temp ^= u >Возврат кабриолета в< T >.Симметричная нота. |
||||
<incrementable<T> > |
<T operator++(T&, int) > |
<T temp(t); ++t >Возврат кабриолета в< T >. |
||||
<decrementable<T> > |
<T operator--(T&, int) > |
<T temp(t); --t; >Возврат кабриолета в< T >. |
||||
<left_shiftable<T> >< left_shiftable1<T> > |
<T operator<<(const T&, const T&) > |
<T temp(t); temp <<= t1 >.Возврат кабриолета в< T >.Симметричная нота. |
||||
<left_shiftable<T,
U> >< left_shiftable2<T, U> > |
<T operator<<(const T&, const U&) > |
<T temp(t); temp <<= u >Возврат кабриолета в< T >.Симметричная нота. |
||||
<right_shiftable<T> >< right_shiftable1<T> > |
<T operator>>(const T&, const T&) > |
<T temp(t); temp >>= t1 >Возврат кабриолета в< T >. См. примечание к симметрии. |
||||
<right_shiftable<T,
U> >< right_shiftable2<T, U> > |
<T operator>>(const T&, const U&) > |
<T temp(t); temp >>= u >Возврат кабриолета в< T >. См. примечание к симметрии. |
||||
<equivalent<T> >< equivalent1<T> > |
<bool operator==(const T&, const T&) > |
<t < t1 >Возврат кабриолета в< bool >. См.Заказная записка. |
||||
<equivalent<T, U> >< equivalent2<T, U> > |
<bool operator==(const T&, const U&) > |
<t < u ><t > u >.Возврат кабриолета в< bool >. См.Заказная записка. |
||||
<partially_ordered<T> >< partially_ordered1<T> > |
<bool operator>(const T&, const T&) >< bool operator<=(const T&, const T&) >< bool operator>=(const T&, const T&) > |
<t < t1 ><t == t1 >.Возврат кабриолета в< bool >. См.Заказная записка. |
||||
<partially_ordered<T,
U> >< partially_ordered2<T, U> > |
<bool operator<=(const T&, const U&) >< bool operator>=(const T&, const U&) >< bool operator>(const U&, const T&) >< bool operator<(const U&, const T&) >< bool operator<=(const U&, const T&) >< bool operator>=(const U&, const T&) > |
<t < u ><t > u ><t ==
u >Возврат кабриолета в< bool >. См.Заказная записка. |
Шаблоны<less_than_comparable<T>
>и<partially_ordered<T>
>обеспечивают одинаковый набор операций. Однако в работах<less_than_comparable<T>
>предполагается, что все значения типа<T
>могут быть размещены в общем порядке. Если это не соответствует действительности, напримерЗначения не-а-числа в арифметике IEEE с плавающей точкой, то<partially_ordered<T>
>следует использовать. Шаблон<partially_ordered<T>
>может использоваться для полностью упорядоченного типа, но он не так эффективен, как<less_than_comparable<T>
>. Это правило также применяется для<less_than_comparable<T, U>
>и<partially_ordered<T,
U>
>в отношении упорядочения всех<T
>и<U
>значений, а также для обеих версий<equivalent<>
>. Решение для<equivalent<>
>заключается в написании пользовательского<operator==
>для целевого класса.
Прежде чем говорить о симметрии, нужно поговорить об оптимизации, чтобы понять причины различных стилей реализации операторов. Давайте рассмотрим<operator+
>для класса<T
>в качестве примера:
T operator+( const T& lhs, const T& rhs ) { return T( lhs ) += rhs; }This would be a normal implementation of
operator+
, but it
is not an efficient one. An unnamed local copy of lhs
is
created, operator+=
is called on it and it is copied to the
function return value (which is another unnamed object of type
T
). The standard doesn't generally allow the intermediate
object to be optimized away:
3.7.2/2: Automatic storage durationThe reference to 12.8 is important for us:
If a named automatic object has initialization or a destructor with side effects, it shall not be destroyed before the end of its block, nor shall it be eliminated as an optimization even if it appears to be unused, except that a class object or its copy may be eliminated as specified in 12.8.
12.8/15: Copying class objectsThis optimization is known as the named return value optimization (NRVO), which leads us to the following implementation for
...
For a function with a class return type, if the expression in the return statement is the name of a local object, and the cv-unqualified type of the local object is the same as the function return type, an implementation is permitted to omit creating the temporary object to hold the function return value, even if the class copy constructor or destructor has side effects.
operator+
:
T operator+( const T& lhs, const T& rhs ) { T nrv( lhs ); nrv += rhs; return nrv; }Given this implementation, the compiler is allowed to remove the intermediate object. Sadly, not all compiler implement the NRVO, some even implement it in an incorrect way which makes it useless here. Without the NRVO, the NRVO-friendly code is no worse than the original code showed above, but there is another possible implementation, which has some very special properties:
T operator+( T lhs, const T& rhs ) { return lhs += rhs; }The difference to the first implementation is that
lhs
is
not taken as a constant reference used to create a copy; instead,
lhs
is a by-value parameter, thus it is already the copy
needed. This allows another optimization (12.2/2) for some cases.
Consider a + b + c
where the result of
a + b
is not copied when used as lhs
when adding c
. This is more efficient than the original
code, but not as efficient as a compiler using the NRVO. For most people,
it is still preferable for compilers that don't implement the NRVO, but
the operator+
now has a different function signature. Also,
the number of objects created differs for
(a + b ) + c
and
a + ( b + c )
. Most probably,
this won't be a problem for you, but if your code relies on the function
signature or a strict symmetric behaviour, you should set
BOOST_FORCE_SYMMETRIC_OPERATORS
in your user-config. This
will force the NRVO-friendly implementation to be used even for compilers
that don't implement the NRVO. Следующие шаблоны предоставляют общие группы связанных операций. Например, так как тип, который можно добавить, обычно также является субподрядным, шаблон<additive
>предоставляет объединенные операторы обоих. Сгруппированные шаблоны операторов имеют дополнительный параметр шаблона<B
>, который не показан, для метода цепей базового класса.
|
|||
Template | Component Operator Templates | ||
---|---|---|---|
<totally_ordered<T> >< totally_ordered1<T> > |
less_than_comparable<T>
equality_comparable<T> |
||
<totally_ordered<T,
U> >< totally_ordered2<T, U> > |
less_than_comparable<T,
U>
equality_comparable<T,
U> |
||
<additive<T> >< additive1<T> > |
addable<T>
subtractable<T> |
||
<additive<T, U> >< additive2<T, U> > |
addable<T, U>
subtractable<T,
U> |
||
<multiplicative<T> >< multiplicative1<T> > |
multipliable<T>
dividable<T> |
||
<multiplicative<T,
U> >< multiplicative2<T, U> > |
multipliable<T,
U>
dividable<T,
U> |
||
<integer_multiplicative<T> >< integer_multiplicative1<T> > |
multiplicative<T>
modable<T> |
||
<integer_multiplicative<T,
U> >< integer_multiplicative2<T, U> > |
multiplicative<T,
U>
modable<T, U> |
||
<arithmetic<T> >< arithmetic1<T> > |
additive<T>
multiplicative<T> |
||
<arithmetic<T, U> >< arithmetic2<T, U> > |
additive<T,
U>
multiplicative<T,
U> |
||
<integer_arithmetic<T> >< integer_arithmetic1<T> > |
additive<T>
integer_multiplicative<T> |
||
<integer_arithmetic<T,
U> >< integer_arithmetic2<T, U> > |
additive<T,
U>
integer_multiplicative<T,
U> |
||
<bitwise<T> >< bitwise1<T> > |
xorable<T>
andable<T> orable<T> |
||
<bitwise<T, U> >< bitwise2<T, U> > |
xorable<T, U>
andable<T, U> orable<T, U> |
||
<unit_steppable<T> > |
incrementable<T>
decrementable<T> |
||
<shiftable<T> >< shiftable1<T> > |
left_shiftable<T>
right_shiftable<T> |
||
<shiftable<T, U> >< shiftable2<T, U> > |
left_shiftable<T,
U>
right_shiftable<T,
U> |
||
<ring_operators<T> >< ring_operators1<T> > |
additive<T>
multipliable<T> |
||
<ring_operators<T,
U> >< ring_operators2<T, U> > |
additive<T,
U>
subtractable2_left<T,
U> multipliable<T,
U> |
||
<ordered_ring_operators<T> >< ordered_ring_operators1<T> > |
ring_operators<T>
totally_ordered<T> |
||
<ordered_ring_operators<T,
U> >< ordered_ring_operators2<T, U> > |
ring_operators<T,
U>
totally_ordered<T,
U> |
||
<field_operators<T> >< field_operators1<T> > |
ring_operators<T>
dividable<T> |
||
<field_operators<T,
U> >< field_operators2<T, U> > |
ring_operators<T,
U>
dividable<T,
U> dividable2_left<T,
U> |
||
<ordered_field_operators<T> >< ordered_field_operators1<T> > |
field_operators<T>
totally_ordered<T> |
||
<ordered_field_operators<T,
U> >< ordered_field_operators2<T, U> > |
field_operators<T,
U>
totally_ordered<T,
U> |
||
<euclidean_ring_operators<T> >< euclidean_ring_operators1<T> > |
ring_operators<T>
dividable<T> modable<T> |
||
<euclidean_ring_operators<T,
U> >< euclidean_ring_operators2<T, U> > |
ring_operators<T,
U>
dividable<T,
U> dividable2_left<T,
U> modable<T, U> modable2_left<T,
U> |
||
<ordered_euclidean_ring_operators<T> >< ordered_euclidean_ring_operators1<T> > |
euclidean_ring_operators<T>
totally_ordered<T> |
||
<ordered_euclidean_ring_operators<T,
U> >< ordered_euclidean_ring_operators2<T, U> > |
euclidean_ring_operators<T,
U>
totally_ordered<T,
U> |
Старые версии Boost. Библиотека операторов использовала "<euclidian
>", но было указано, что "<euclidean
>" является более распространенным правописанием. Чтобы быть совместимой со старой версией, библиотека теперь поддерживает оба написания.
Шаблоны классов арифметических операторов<operators<>
>и<operators2<>
>являются примерами классов групп нерасширяемых операторов. Эти шаблоны унаследованных классов из предыдущих версий заголовка не могут быть использованы дляцепей базового класса.
|
|||
Template | Component Operator Templates | ||
---|---|---|---|
<operators<T> > |
totally_ordered<T>
integer_arithmetic<T> bitwise<T> unit_steppable<T> |
||
<operators<T, U> >< operators2<T, U> > |
totally_ordered<T,
U>
integer_arithmetic<T,
U> bitwise<T, U> |
Программаoperators_test.cppдемонстрирует использование шаблонов арифметических операторов, а также может быть использована для проверки правильности работы. Проверьте отчет о состоянии компилятора для результатов тестирования на выбранных платформах.
Помощник итераторашаблонов облегчает задачу создания пользовательского итератора. Подобно арифметическим типам, полный итератор имеет множество операторов, которые являются «избыточными» и могут быть реализованы с точки зрения основного набора операторов.
Операторыdereferenceбыли мотивированы помощникамиитератора, но часто полезны и в контекстах, не связанных с итератором. Многие из резервных операторов итератора также являются арифметическими операторами, поэтому классы помощников итератора заимствуют многие из операторов, определенных выше. На самом деле, только два новых оператора должны быть определены (указатель к члену<operator->
>и подстрочный<operator[]
>)!
Требования к типам, используемым для инстанцирования операторов отсчета, определяются с точки зрения выражений, которые должны быть действительными, и типа их возврата. Составные шаблоны оператора перечисляют свои шаблоны компонентов, которые должен поддерживать и, возможно, другие требования.
Все шаблоны оператора отсчета в этой таблице принимают необязательный параметр шаблона (не показан), который используется дляцепей базового класса.
|
||||||||
Template | Supplied Operations | Requirements | ||||||
---|---|---|---|---|---|---|---|---|
<dereferenceable<T,
P> > |
<P operator->() const > |
<(&*i) >. Возврат кабриолета в<P >. |
||||||
<indexable<T, D,
R> > |
<R operator[](D n) const > |
<*(i + n) >. Возвращение типа<R >. |
Существует пять шаблонов оператора итератора, каждый для разных категорий итераторов. В следующей таблице показаны группы операторов для любой категории, которую может определить пользовательский итератор. Эти шаблоны классов имеют дополнительный дополнительный параметр шаблона<B
>, который не показан, для поддержки цепей базового класса.
|
|||||||
Template | Component Operator Templates | ||||||
---|---|---|---|---|---|---|---|
<input_iteratable<T,
P> > |
equality_comparable<T>
incrementable<T> dereferenceable<T,
P> |
||||||
<output_iteratable<T> > |
incrementable<T>
[ORIG_END] --> |
||||||
<forward_iteratable<T,
P> > |
input_iteratable<T,
P>
[ORIG_END] --> |
||||||
<bidirectional_iteratable<T,
P> > |
forward_iteratable<T,
P>
decrementable<T> |
||||||
<random_access_iteratable<T, P, D,
R> > |
bidirectional_iteratable<T,
P>
totally_ordered<T> additive<T,
D> indexable<T, D,
R> |
Существует также пять шаблонов класса помощников итератора, каждый из которых соответствует отдельной категории итератора. Эти классы не могут быть использованы для цепей базового класса. Следующие резюме показывают, что эти шаблоны классов предоставляют как операторы итератора из шаблоновитератора оператора класса, так и шаблоны типа итератора, требуемые стандартом C++<iterator_category
>,<value_type
>,и т. Д..
|
|||||||
Template | Operations & Requirements | ||||||
---|---|---|---|---|---|---|---|
<input_iterator_helper<T,
V, D, P, R> > |
Поддерживает операции и имеет требования
input_iteratable<T,
P>
[ORIG_END] --> |
||||||
<output_iterator_helper<T> > |
Поддерживает операции и имеет требования
output_iteratable<T>
See also [1], [2].
[ORIG_END] --> |
||||||
<forward_iterator_helper<T, V, D, P,
R> > |
Поддерживает операции и имеет требования
forward_iteratable<T,
P>
[ORIG_END] --> |
||||||
<bidirectional_iterator_helper<T,
V, D, P, R> > |
Поддерживает операции и имеет требования
bidirectional_iteratable<T,
P>
[ORIG_END] --> |
||||||
<random_access_iterator_helper<T,
V, D, P, R> > |
Поддерживает операции и имеет требования
x1 - x2 >с возвратным конвертируемым в<D >также требуется.random_access_iteratable<T, P, D,
R>
To satisfy RandomAccessIterator,
x1 - x2 with return convertible to D is
also required.
[ORIG_END] --> |
В отличие от других шаблонов помощников итератора,<output_iterator_helper
>принимает только один параметр шаблона — тип его целевого класса. Хотя для некоторых это может показаться ненужным ограничением, стандарт требует, чтобы<difference_type
>и<value_type
>любого итератора вывода были<void
>(24.3.1 [lib.iterator.traits]), и<output_iterator_helper
>шаблон соблюдает это требование. Кроме того, выходные итераторы в стандарте имеют пустотные<pointer
>и<reference
>типы, поэтому<output_iterator_helper
>делает то же самое.
Поскольку самопрокси является наиболее простым и распространенным способом реализации выходных итераторов (см., например, вставку [24.4.2] и потоковые итераторы [24.5] в стандартной библиотеке),<output_iterator_helper
>поддерживает идиому, определяя<operator*
>и<operator++
>функции-члены, которые просто возвращают неконстантную ссылку на сам итератор. Поддержка самостоятельного прокси-сервера позволяет во многих случаях свести задачу написания выходного итератора к написанию всего двух членских функций — соответствующего конструктора и оператора копирования. Например, вот возможная реализация<boost::function_output_iterator
>адаптера:
template<class UnaryFunction> struct function_output_iterator : boost::output_iterator_helper< function_output_iterator<UnaryFunction> > { explicit function_output_iterator(UnaryFunction const& f = UnaryFunction()) : func(f) {} template<typename T> function_output_iterator& operator=(T const& value) { this->func(value); return *this; } private: UnaryFunction func; };
Обратите внимание, что поддержка самостоятельного прокси-сервера не мешает вам использовать<output_iterator_helper
>для облегчения реализации любого другого, другого типа итератора вывода. Если целевой тип<output_iterator_helper
>дает свое собственное определение<operator*
>или<operator++
>, то эти операторы будут использоваться, а те, которые поставляются<output_iterator_helper
>, никогда не будут реализованы.
Программаiterators_test.cppдемонстрирует использование шаблонов итератора, а также может использоваться для проверки правильности работы. Ниже приведен пользовательский итератор, определенный в программе тестирования. Он демонстрирует правильную (хотя и тривиальную) реализацию основных операций, которые должны быть определены для того, чтобы помощники итератора «заполнили» остальные операции итератора.
template <class T, class R, class P> struct test_iter : public boost::random_access_iterator_helper< test_iter<T,R,P>, T, std::ptrdiff_t, P, R> { typedef test_iter self; typedef R Reference; typedef std::ptrdiff_t Distance; public: explicit test_iter(T* i =0); test_iter(const self& x); self& operator=(const self& x); Reference operator*() const; self& operator++(); self& operator--(); self& operator+=(Distance n); self& operator-=(Distance n); bool operator==(const self& x) const; bool operator<(const self& x) const; friend Distance operator-(const self& x, const self& y); };
Проверьте отчет о состоянии компиляторадля результатов испытаний с выбранными платформами.
Измененияв интерфейсе библиотеки и рекомендуемое использованиебыли мотивированы некоторыми практическими проблемами, описанными ниже. Новая версия библиотеки по-прежнему обратно совместима с предыдущей (так что вы невынужденыизменять какой-либо существующий код), но старое использование обесценено. Хотя это было, возможно, проще и интуитивно понятнее, чем использование цепей базовых классов, было обнаружено, что старая практика получения из нескольких шаблонов операторов может привести к тому, что полученные классы будут намного больше, чем они должны быть. Большинство современных компиляторов C++ значительно раздувают размер классов, полученных из нескольких пустых базовых классов, хотя сами базовые классы не имеют состояния. Например, размер<point<int>
>из примеравыше составлял 12-24 байта на различных компиляторах платформы Win32, вместо ожидаемых 8 байтов.
Строго говоря, это не было ошибкой библиотеки - языковые правила позволяют компилятору применять оптимизацию пустого базового класса в этой ситуации. В принципе произвольное число пустых базовых классов может быть распределено при том же смещении при условии, что ни один из них не имеет общего предка (см. пункт 5 раздела 10.5 стандарта). Но определение языка также не требуетреализациидля оптимизации, и лишь немногие из сегодняшних компиляторов реализуют его, когда речь идет о множественном наследовании. Что еще хуже, очень маловероятно, что реализаторы примут его в качестве будущего улучшения существующих компиляторов, потому что это нарушит бинарную совместимость между кодом, генерируемым двумя различными версиями одного и того же компилятора. Как сказал Мэтт Остерн: «Один из немногих случаев, когда у вас есть свобода делать такие вещи, это когда вы ориентируетесь на новую архитектуру». С другой стороны, многие распространенные компиляторы будут использовать оптимизацию пустой базы для отдельных иерархий наследования.
Учитывая важность проблемы для пользователей библиотеки (которая направлена на то, чтобы быть полезной для написания легких классов, таких как<MyInt
>или<point<>
>), и силы, описанные выше, мы решили изменить интерфейс библиотеки так, чтобы раздувание размера объекта можно было устранить даже на компиляторах, которые поддерживают только простейшую форму оптимизации пустого базового класса. Современный библиотечный интерфейс является результатом этих изменений. Хотя новое использование немного сложнее старого, мы считаем, что стоит сделать библиотеку более полезной в реальном мире. Алексей Гуртовой внес код, который поддерживает новую идиому использования, позволяя библиотеке оставаться обратно совместимой.
Пересмотрено: 7 августа 2008
Copyright © Beman Dawes, David Abrahams, 1999-2001.
Copyright © Daniel Frey, 2002-2009.
Использование, модификация и распространение подчиняются Boost Software Лицензия, версия 1.0. (См. сопроводительный файл LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)[ORIG_END] -->
Статья Header <boost/operators.hpp> Documentation раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |