mirror of
https://github.com/boostorg/type_traits.git
synced 2026-04-28 18:12:06 +02:00
Update docs for binary operator traits.
This commit is contained in:
+1
-56
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[has_binary_operator_compat]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator&` is public or not:
|
||||
if `operator&` is defined as a private member of `Lhs` then
|
||||
instantiating `has_bit_and<Lhs>` will produce a compiler error.
|
||||
For this reason `has_bit_and` cannot be used to determine whether a type has a public `operator&` or not.
|
||||
``
|
||||
struct A { private: void operator&(const A&); };
|
||||
boost::has_bit_and<A>::value; // error: A::operator&(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator&(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_bit_and<A>::value; // this is fine
|
||||
boost::has_bit_and<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator&` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_bit_and.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator&(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_bit_and< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g&g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_bit_and< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b&b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_bit_and..&..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator&=` is public or not:
|
||||
if `operator&=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_bit_and_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_bit_and_assign` cannot be used to determine whether a type has a public `operator&=` or not.
|
||||
``
|
||||
struct A { private: void operator&=(const A&); };
|
||||
boost::has_bit_and_assign<A>::value; // error: A::operator&=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator&=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_bit_and_assign<A>::value; // this is fine
|
||||
boost::has_bit_and_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator&=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_bit_and_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator&=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_bit_and_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g&=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_bit_and_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b&=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_bit_and_assign..&=..A&..contains<T>&..[/Nothing]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator|` is public or not:
|
||||
if `operator|` is defined as a private member of `Lhs` then
|
||||
instantiating `has_bit_or<Lhs>` will produce a compiler error.
|
||||
For this reason `has_bit_or` cannot be used to determine whether a type has a public `operator|` or not.
|
||||
``
|
||||
struct A { private: void operator|(const A&); };
|
||||
boost::has_bit_or<A>::value; // error: A::operator|(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator|(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_bit_or<A>::value; // this is fine
|
||||
boost::has_bit_or<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator|` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_bit_or.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator|(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_bit_or< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g|g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_bit_or< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b|b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_bit_or..|..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator|=` is public or not:
|
||||
if `operator|=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_bit_or_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_bit_or_assign` cannot be used to determine whether a type has a public `operator|=` or not.
|
||||
``
|
||||
struct A { private: void operator|=(const A&); };
|
||||
boost::has_bit_or_assign<A>::value; // error: A::operator|=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator|=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_bit_or_assign<A>::value; // this is fine
|
||||
boost::has_bit_or_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator|=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_bit_or_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator|=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_bit_or_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g|=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_bit_or_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b|=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_bit_or_assign..|=..A&..contains<T>&..[/Nothing]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator^` is public or not:
|
||||
if `operator^` is defined as a private member of `Lhs` then
|
||||
instantiating `has_bit_xor<Lhs>` will produce a compiler error.
|
||||
For this reason `has_bit_xor` cannot be used to determine whether a type has a public `operator^` or not.
|
||||
``
|
||||
struct A { private: void operator^(const A&); };
|
||||
boost::has_bit_xor<A>::value; // error: A::operator^(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator^(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_bit_xor<A>::value; // this is fine
|
||||
boost::has_bit_xor<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator^` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_bit_xor.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator^(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_bit_xor< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g^g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_bit_xor< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b^b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_bit_xor..^..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator^=` is public or not:
|
||||
if `operator^=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_bit_xor_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_bit_xor_assign` cannot be used to determine whether a type has a public `operator^=` or not.
|
||||
``
|
||||
struct A { private: void operator^=(const A&); };
|
||||
boost::has_bit_xor_assign<A>::value; // error: A::operator^=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator^=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_bit_xor_assign<A>::value; // this is fine
|
||||
boost::has_bit_xor_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator^=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_bit_xor_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator^=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_bit_xor_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g^=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_bit_xor_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b^=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_bit_xor_assign..^=..A&..contains<T>&..[/Nothing]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator/` is public or not:
|
||||
if `operator/` is defined as a private member of `Lhs` then
|
||||
instantiating `has_divides<Lhs>` will produce a compiler error.
|
||||
For this reason `has_divides` cannot be used to determine whether a type has a public `operator/` or not.
|
||||
``
|
||||
struct A { private: void operator/(const A&); };
|
||||
boost::has_divides<A>::value; // error: A::operator/(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator/(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_divides<A>::value; // this is fine
|
||||
boost::has_divides<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator/` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_divides.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator/(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_divides< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g/g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_divides< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b/b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_divides../..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator/=` is public or not:
|
||||
if `operator/=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_divides_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_divides_assign` cannot be used to determine whether a type has a public `operator/=` or not.
|
||||
``
|
||||
struct A { private: void operator/=(const A&); };
|
||||
boost::has_divides_assign<A>::value; // error: A::operator/=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator/=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_divides_assign<A>::value; // this is fine
|
||||
boost::has_divides_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator/=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_divides_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator/=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_divides_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g/=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_divides_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b/=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_divides_assign../=..A&..contains<T>&..[/Nothing]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator==` is public or not:
|
||||
if `operator==` is defined as a private member of `Lhs` then
|
||||
instantiating `has_equal_to<Lhs>` will produce a compiler error.
|
||||
For this reason `has_equal_to` cannot be used to determine whether a type has a public `operator==` or not.
|
||||
``
|
||||
struct A { private: void operator==(const A&); };
|
||||
boost::has_equal_to<A>::value; // error: A::operator==(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator==(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_equal_to<A>::value; // this is fine
|
||||
boost::has_equal_to<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator==` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_equal_to.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator==(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_equal_to< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g==g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_equal_to< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b==b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_equal_to..==..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator>` is public or not:
|
||||
if `operator>` is defined as a private member of `Lhs` then
|
||||
instantiating `has_greater<Lhs>` will produce a compiler error.
|
||||
For this reason `has_greater` cannot be used to determine whether a type has a public `operator>` or not.
|
||||
``
|
||||
struct A { private: void operator>(const A&); };
|
||||
boost::has_greater<A>::value; // error: A::operator>(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator>(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_greater<A>::value; // this is fine
|
||||
boost::has_greater<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator>` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_greater.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator>(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_greater< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g>g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_greater< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b>b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_greater..>..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator>=` is public or not:
|
||||
if `operator>=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_greater_equal<Lhs>` will produce a compiler error.
|
||||
For this reason `has_greater_equal` cannot be used to determine whether a type has a public `operator>=` or not.
|
||||
``
|
||||
struct A { private: void operator>=(const A&); };
|
||||
boost::has_greater_equal<A>::value; // error: A::operator>=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator>=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_greater_equal<A>::value; // this is fine
|
||||
boost::has_greater_equal<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator>=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_greater_equal.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator>=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_greater_equal< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g>=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_greater_equal< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b>=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_greater_equal..>=..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -49,62 +49,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator<<` is public or not:
|
||||
if `operator<<` is defined as a private member of `Lhs` then
|
||||
instantiating `has_left_shift<Lhs>` will produce a compiler error.
|
||||
For this reason `has_left_shift` cannot be used to determine whether a type has a public `operator<<` or not.
|
||||
``
|
||||
struct A { private: void operator<<(const A&); };
|
||||
boost::has_left_shift<A>::value; // error: A::operator<<(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator<<(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_left_shift<A>::value; // this is fine
|
||||
boost::has_left_shift<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator<<` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_left_shift.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator<<(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_left_shift< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g<<g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_left_shift< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b<<b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_left_shift..<<..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator<<=` is public or not:
|
||||
if `operator<<=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_left_shift_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_left_shift_assign` cannot be used to determine whether a type has a public `operator<<=` or not.
|
||||
``
|
||||
struct A { private: void operator<<=(const A&); };
|
||||
boost::has_left_shift_assign<A>::value; // error: A::operator<<=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator<<=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_left_shift_assign<A>::value; // this is fine
|
||||
boost::has_left_shift_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator<<=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_left_shift_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator<<=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_left_shift_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g<<=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_left_shift_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b<<=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_left_shift_assign..<<=..A&..contains<T>&..[/]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator<` is public or not:
|
||||
if `operator<` is defined as a private member of `Lhs` then
|
||||
instantiating `has_less<Lhs>` will produce a compiler error.
|
||||
For this reason `has_less` cannot be used to determine whether a type has a public `operator<` or not.
|
||||
``
|
||||
struct A { private: void operator<(const A&); };
|
||||
boost::has_less<A>::value; // error: A::operator<(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator<(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_less<A>::value; // this is fine
|
||||
boost::has_less<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator<` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_less.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator<(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_less< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g<g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_less< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b<b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_less..<..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator<=` is public or not:
|
||||
if `operator<=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_less_equal<Lhs>` will produce a compiler error.
|
||||
For this reason `has_less_equal` cannot be used to determine whether a type has a public `operator<=` or not.
|
||||
``
|
||||
struct A { private: void operator<=(const A&); };
|
||||
boost::has_less_equal<A>::value; // error: A::operator<=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator<=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_less_equal<A>::value; // this is fine
|
||||
boost::has_less_equal<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator<=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_less_equal.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator<=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_less_equal< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g<=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_less_equal< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b<=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_less_equal..<=..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -46,63 +46,8 @@ __examples
|
||||
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
[binary_operator_known_issues has_logical_and..&&..bool..bool..const ]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator&&` is public or not:
|
||||
if `operator&&` is defined as a private member of `Lhs` then
|
||||
instantiating `has_logical_and<Lhs>` will produce a compiler error.
|
||||
For this reason `has_logical_and` cannot be used to determine whether a type has a public `operator&&` or not.
|
||||
``
|
||||
struct A { private: void operator&&(const A&); };
|
||||
boost::has_logical_and<A>::value; // error: A::operator&&(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator&&(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_logical_and<A>::value; // this is fine
|
||||
boost::has_logical_and<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator&&` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_logical_and.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator&&(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_logical_and< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g&&g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_logical_and< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b&&b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -47,62 +47,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator||` is public or not:
|
||||
if `operator||` is defined as a private member of `Lhs` then
|
||||
instantiating `has_logical_or<Lhs>` will produce a compiler error.
|
||||
For this reason `has_logical_or` cannot be used to determine whether a type has a public `operator||` or not.
|
||||
``
|
||||
struct A { private: void operator||(const A&); };
|
||||
boost::has_logical_or<A>::value; // error: A::operator||(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator||(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_logical_or<A>::value; // this is fine
|
||||
boost::has_logical_or<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator||` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_logical_or.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator||(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_logical_or< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g||g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_logical_or< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b||b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_logical_or..||..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator-` is public or not:
|
||||
if `operator-` is defined as a private member of `Lhs` then
|
||||
instantiating `has_minus<Lhs>` will produce a compiler error.
|
||||
For this reason `has_minus` cannot be used to determine whether a type has a public `operator-` or not.
|
||||
``
|
||||
struct A { private: void operator-(const A&); };
|
||||
boost::has_minus<A>::value; // error: A::operator-(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator-(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_minus<A>::value; // this is fine
|
||||
boost::has_minus<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator-` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_minus.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator-(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_minus< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g-g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_minus< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b-b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_minus..-..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator-=` is public or not:
|
||||
if `operator-=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_minus_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_minus_assign` cannot be used to determine whether a type has a public `operator-=` or not.
|
||||
``
|
||||
struct A { private: void operator-=(const A&); };
|
||||
boost::has_minus_assign<A>::value; // error: A::operator-=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator-=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_minus_assign<A>::value; // this is fine
|
||||
boost::has_minus_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator-=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_minus_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator-=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_minus_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g-=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_minus_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b-=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_minus_assign..-=..A&..contains<T>&..[/]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator%` is public or not:
|
||||
if `operator%` is defined as a private member of `Lhs` then
|
||||
instantiating `has_modulus<Lhs>` will produce a compiler error.
|
||||
For this reason `has_modulus` cannot be used to determine whether a type has a public `operator%` or not.
|
||||
``
|
||||
struct A { private: void operator%(const A&); };
|
||||
boost::has_modulus<A>::value; // error: A::operator%(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator%(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_modulus<A>::value; // this is fine
|
||||
boost::has_modulus<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator%` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_modulus.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator%(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_modulus< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g%g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_modulus< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b%b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_modulus..%..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator%=` is public or not:
|
||||
if `operator%=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_modulus_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_modulus_assign` cannot be used to determine whether a type has a public `operator%=` or not.
|
||||
``
|
||||
struct A { private: void operator%=(const A&); };
|
||||
boost::has_modulus_assign<A>::value; // error: A::operator%=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator%=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_modulus_assign<A>::value; // this is fine
|
||||
boost::has_modulus_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator%=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_modulus_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator%=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_modulus_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g%=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_modulus_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b%=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_modulus_assign..%=..A&..contains<T>&..[/]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator*` is public or not:
|
||||
if `operator*` is defined as a private member of `Lhs` then
|
||||
instantiating `has_multiplies<Lhs>` will produce a compiler error.
|
||||
For this reason `has_multiplies` cannot be used to determine whether a type has a public `operator*` or not.
|
||||
``
|
||||
struct A { private: void operator*(const A&); };
|
||||
boost::has_multiplies<A>::value; // error: A::operator*(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator*(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_multiplies<A>::value; // this is fine
|
||||
boost::has_multiplies<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator*` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_multiplies.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator*(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_multiplies< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g*g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_multiplies< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b*b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_multiplies..*..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator*=` is public or not:
|
||||
if `operator*=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_multiplies_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_multiplies_assign` cannot be used to determine whether a type has a public `operator*=` or not.
|
||||
``
|
||||
struct A { private: void operator*=(const A&); };
|
||||
boost::has_multiplies_assign<A>::value; // error: A::operator*=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator*=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_multiplies_assign<A>::value; // this is fine
|
||||
boost::has_multiplies_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator*=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_multiplies_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator*=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_multiplies_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g*=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_multiplies_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b*=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_multiplies_assign..*=..A&..contains<T>&..[/]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator!=` is public or not:
|
||||
if `operator!=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_not_equal_to<Lhs>` will produce a compiler error.
|
||||
For this reason `has_not_equal_to` cannot be used to determine whether a type has a public `operator!=` or not.
|
||||
``
|
||||
struct A { private: void operator!=(const A&); };
|
||||
boost::has_not_equal_to<A>::value; // error: A::operator!=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator!=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_not_equal_to<A>::value; // this is fine
|
||||
boost::has_not_equal_to<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator!=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_not_equal_to.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator!=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_not_equal_to< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g!=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_not_equal_to< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b!=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_not_equal_to..!=..bool..bool..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator+` is public or not:
|
||||
if `operator+` is defined as a private member of `Lhs` then
|
||||
instantiating `has_plus<Lhs>` will produce a compiler error.
|
||||
For this reason `has_plus` cannot be used to determine whether a type has a public `operator+` or not.
|
||||
``
|
||||
struct A { private: void operator+(const A&); };
|
||||
boost::has_plus<A>::value; // error: A::operator+(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator+(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_plus<A>::value; // this is fine
|
||||
boost::has_plus<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator+` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_plus.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator+(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_plus< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g+g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_plus< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b+b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_plus..+..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -48,62 +48,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator+=` is public or not:
|
||||
if `operator+=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_plus_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_plus_assign` cannot be used to determine whether a type has a public `operator+=` or not.
|
||||
``
|
||||
struct A { private: void operator+=(const A&); };
|
||||
boost::has_plus_assign<A>::value; // error: A::operator+=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator+=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_plus_assign<A>::value; // this is fine
|
||||
boost::has_plus_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator+=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_plus_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator+=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_plus_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g+=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_plus_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b+=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_plus_assign..+=..A&..contains<T>&..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
+1
-56
@@ -49,62 +49,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator>>` is public or not:
|
||||
if `operator>>` is defined as a private member of `Lhs` then
|
||||
instantiating `has_right_shift<Lhs>` will produce a compiler error.
|
||||
For this reason `has_right_shift` cannot be used to determine whether a type has a public `operator>>` or not.
|
||||
``
|
||||
struct A { private: void operator>>(const A&); };
|
||||
boost::has_right_shift<A>::value; // error: A::operator>>(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator>>(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_right_shift<A>::value; // this is fine
|
||||
boost::has_right_shift<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator>>` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_right_shift.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator>>(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_right_shift< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g>>g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_right_shift< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b>>b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_right_shift..>>..A..contains<T>..const ]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -46,62 +46,7 @@ __examples
|
||||
|
||||
[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
|
||||
|
||||
[*Known issues:]
|
||||
|
||||
* This trait cannot detect whether binary `operator>>=` is public or not:
|
||||
if `operator>>=` is defined as a private member of `Lhs` then
|
||||
instantiating `has_right_shift_assign<Lhs>` will produce a compiler error.
|
||||
For this reason `has_right_shift_assign` cannot be used to determine whether a type has a public `operator>>=` or not.
|
||||
``
|
||||
struct A { private: void operator>>=(const A&); };
|
||||
boost::has_right_shift_assign<A>::value; // error: A::operator>>=(const A&) is private
|
||||
``
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
``
|
||||
struct A { };
|
||||
void operator>>=(const A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::has_right_shift_assign<A>::value; // this is fine
|
||||
boost::has_right_shift_assign<B>::value; // error: ambiguous overload
|
||||
``
|
||||
|
||||
* There is an issue when applying this trait to template classes.
|
||||
If `operator>>=` is defined but does not bind for a given template type,
|
||||
it is still detected by the trait which returns `true` instead of `false`.
|
||||
Example:
|
||||
``
|
||||
#include <boost/type_traits/has_right_shift_assign.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains { T data; };
|
||||
|
||||
template <class T>
|
||||
bool operator>>=(const contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
bool f(const good&, const good&) { }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::has_right_shift_assign< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g>>=g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::has_right_shift_assign< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b>>=b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
``
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
[binary_operator_known_issues has_right_shift_assign..>>=..A&..contains<T>&..[/]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -107,68 +107,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_bit_and</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_bit_and</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">&(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator&(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">&(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_bit_and</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_bit_and.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_bit_and cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_bit_and<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> & <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_and<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_and<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>&
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>&
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_bit_and<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_bit_and</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>&
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> & <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_and<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator & (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> & <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_and<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_and<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -107,68 +107,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">&=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">&=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_bit_and_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_bit_and_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">&=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">&=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator&=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">&=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">&=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_bit_and_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_bit_and_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_bit_and_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_bit_and_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> &= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_and_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_and_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_and_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>&=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>&=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_bit_and_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_bit_and_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>&= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> &= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_and_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator &= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> &= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_and_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_and_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -107,66 +107,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_bit_or</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_bit_or</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">|(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator|(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">|(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">|</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_bit_or</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_bit_or.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_bit_or cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_bit_or<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">|(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> | <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">|</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">|</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_or<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_or<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>|
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>|
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_bit_or<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_bit_or</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>|
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> | <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_or<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator | (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> | <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_or<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_or<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -107,68 +107,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">|=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">|=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_bit_or_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_bit_or_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">|=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">|=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator|=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">|=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">|=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_bit_or_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_bit_or_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_bit_or_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_bit_or_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">|=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> |= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">|=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_or_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">|=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_or_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_or_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>|=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>|=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_bit_or_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_bit_or_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>|= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> |= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_or_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator |= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> |= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_or_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_or_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -107,66 +107,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">^</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">^</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_bit_xor</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_bit_xor</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">^</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">^(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator^(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">^(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">^</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_bit_xor</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_bit_xor.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_bit_xor cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_bit_xor<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">^(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> ^ <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">^</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">^</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_xor<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_xor<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>^
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>^
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_bit_xor<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_bit_xor</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>^
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> ^ <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_xor<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator ^ (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> ^ <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_xor<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_xor<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -107,68 +107,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">^=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">^=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_bit_xor_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_bit_xor_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">^=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">^=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator^=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">^=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">^=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_bit_xor_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_bit_xor_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_bit_xor_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_bit_xor_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">^=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> ^= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">^=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_bit_xor_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">^=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_xor_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_bit_xor_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>^=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>^=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_bit_xor_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_bit_xor_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>^= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> ^= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_xor_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator ^= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> ^= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_xor_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_bit_xor_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,66 +113,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">/</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">/</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_divides</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_divides</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">/</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">/(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator/(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">/(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">/</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_divides</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_divides.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_divides cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_divides<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">/(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> / <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">/</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">/</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_divides<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_divides<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>/
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>/
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_divides<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_divides</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>/
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> / <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_divides<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator / (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> / <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_divides<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_divides<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,68 +113,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">/=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">/=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_divides_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_divides_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">/=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">/=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator/=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">/=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">/=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_divides_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_divides_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_divides_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_divides_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">/=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> /= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">/=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_divides_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">/=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_divides_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_divides_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>/=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>/=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_divides_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_divides_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>/= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> /= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_divides_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator /= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> /= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_divides_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_divides_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -112,68 +112,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_equal_to</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator==(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_equal_to</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_equal_to.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_equal_to cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_equal_to<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> == <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">==</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">==</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_equal_to<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_equal_to<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>==
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>==
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_equal_to<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_equal_to</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>==
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> == <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_equal_to<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator == (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> == <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_equal_to<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_equal_to<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -112,68 +112,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">></span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">></span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_greater</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_greater</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">></span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator>(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">></span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_greater</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_greater.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_greater cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_greater<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">>(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> > <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">></span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">></span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_greater<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_greater<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>>
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_greater<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_greater</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>>
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> > <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_greater<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator > (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> > <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_greater<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_greater<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -112,68 +112,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">>=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">>=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_greater_equal</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_greater_equal</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">>=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater_equal</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator>=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater_equal</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater_equal</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">>=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_greater_equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_greater_equal.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_greater_equal
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_greater_equal<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">>=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> >= <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater_equal</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">>=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_greater_equal</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">>=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_greater_equal<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_greater_equal<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>>=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>>=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_greater_equal<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_greater_equal</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>>= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> >= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_greater_equal<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator >= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> >= <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_greater_equal<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_greater_equal<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -119,68 +119,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_left_shift</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_left_shift</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><<(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator<<(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><<(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_left_shift</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_left_shift.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_left_shift
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_left_shift<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special"><<(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> << <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special"><<</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special"><<</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_left_shift<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_left_shift<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code><<
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code><<
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_left_shift<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_left_shift</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code><< or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> << <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_left_shift<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator << (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> << <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_left_shift<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_left_shift<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -107,68 +107,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_left_shift_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_left_shift_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><<=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator<<=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><<=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_left_shift_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_left_shift_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_left_shift_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_left_shift_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special"><<=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> <<= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special"><<=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_left_shift_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special"><<=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_left_shift_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_left_shift_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code><<=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code><<=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_left_shift_assign<Lhs></code>
|
||||
will produce a compiler error. For this reason <code class="literal">has_left_shift_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code><<= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> <<= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_left_shift_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator <<= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> <<= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_left_shift_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_left_shift_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -112,68 +112,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special"><</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special"><</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_less</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_less</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special"><</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator<(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special"><</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_less</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_less.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_less cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_less<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special"><(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> < <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special"><</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special"><</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_less<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_less<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code><
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code><
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_less<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_less</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code><
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> < <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_less<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator < (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> < <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_less<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_less<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -112,68 +112,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special"><=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special"><=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_less_equal</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_less_equal</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special"><=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less_equal</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator<=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special"><=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less_equal</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less_equal</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special"><=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_less_equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_less_equal.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_less_equal
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_less_equal<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special"><=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> <= <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less_equal</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special"><=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_less_equal</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special"><=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_less_equal<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_less_equal<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code><=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code><=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_less_equal<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_less_equal</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code><= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> <= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_less_equal<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator <= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> <= <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_less_equal<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_less_equal<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -110,68 +110,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">&&</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">&&</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_logical_and</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_logical_and</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">&&</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">&&(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_and</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator&&(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">&&(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_and</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_and</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">&&</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_logical_and</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_logical_and.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_logical_and
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_logical_and<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&&(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> && <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_and</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_and</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_logical_and<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_logical_and<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>&&
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>&&
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_logical_and<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_logical_and</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>&& or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> && <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_logical_and<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator && (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> && <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_logical_and<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_logical_and<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -110,68 +110,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_logical_or</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_logical_or</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">||(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_or</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator||(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">||(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_or</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_or</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">||</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_logical_or</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_logical_or.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_logical_or
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_logical_or<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">||(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> || <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_or</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">||</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_logical_or</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">||</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_logical_or<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_logical_or<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>||
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>||
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_logical_or<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_logical_or</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>|| or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> || <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_logical_or<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator || (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> || <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_logical_or<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_logical_or<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,66 +113,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_minus</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_minus</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator-(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_minus</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_minus.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_minus cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_minus<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> - <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">-</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">-</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_minus<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_minus<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>-
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>-
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_minus<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_minus</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>-
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> - <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_minus<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator - (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> - <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_minus<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_minus<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,68 +113,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">-=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">-=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_minus_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_minus_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">-=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator-=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">-=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_minus_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_minus_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_minus_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_minus_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> -= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">-=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_minus_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">-=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_minus_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_minus_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>-=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>-=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_minus_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_minus_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>-= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> -= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_minus_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator -= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> -= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_minus_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_minus_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -106,66 +106,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">%</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">%</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_modulus</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_modulus</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">%</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">%(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator%(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">%(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">%</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_modulus</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_modulus.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_modulus cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_modulus<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">%(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> % <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">%</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">%</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_modulus<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_modulus<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>%
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>%
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_modulus<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_modulus</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>%
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> % <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_modulus<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator % (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> % <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_modulus<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_modulus<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -106,68 +106,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">%=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">%=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_modulus_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_modulus_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">%=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">%=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator%=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">%=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">%=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_modulus_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_modulus_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_modulus_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_modulus_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">%=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> %= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">%=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_modulus_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">%=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_modulus_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_modulus_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>%=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>%=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_modulus_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_modulus_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>%= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> %= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_modulus_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator %= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> %= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_modulus_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_modulus_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,66 +113,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_multiplies</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_multiplies</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">*(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator*(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">*(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_multiplies</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_multiplies.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_multiplies
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_multiplies<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">*(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> * <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">*</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">*</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_multiplies<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_multiplies<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>*
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>*
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_multiplies<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_multiplies</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>* or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> * <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_multiplies<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator * (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> * <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_multiplies<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_multiplies<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,68 +113,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">*=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">*=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_multiplies_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_multiplies_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">*=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">*=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator*=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">*=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">*=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_multiplies_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_multiplies_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_multiplies_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_multiplies_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">*=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> *= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">*=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_multiplies_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">*=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_multiplies_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_multiplies_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>*=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>*=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_multiplies_assign<Lhs></code>
|
||||
will produce a compiler error. For this reason <code class="literal">has_multiplies_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>*= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> *= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_multiplies_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator *= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> *= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_multiplies_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_multiplies_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -112,68 +112,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">!=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">!=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_not_equal_to</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_not_equal_to</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">!=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_not_equal_to</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator!=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_not_equal_to</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_not_equal_to</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">!=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_not_equal_to</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_not_equal_to.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_not_equal_to
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_not_equal_to<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
bool <span class="keyword">operator</span> != <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_not_equal_to</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">!=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_not_equal_to</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">!=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_not_equal_to<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_not_equal_to<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>!=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>!=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_not_equal_to<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_not_equal_to</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>!= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> bool <span class="keyword">operator</span> != <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_not_equal_to<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator != (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
bool <span class="keyword">operator</span> != <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_not_equal_to<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_not_equal_to<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,66 +113,82 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">+</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">+</span></code> is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code> then instantiating <code class="computeroutput"><span class="identifier">has_plus</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code>
|
||||
will produce a compiler error. For this reason <code class="computeroutput"><span class="identifier">has_plus</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">+</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator+(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">+</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_plus</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_plus.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_plus cannot
|
||||
perform introspection of the template function body to ensure that the type
|
||||
meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_plus<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">+(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> + <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">+</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">+</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_plus<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_plus<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>+
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>+
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_plus<Lhs></code> will produce
|
||||
a compiler error. For this reason <code class="literal">has_plus</code> cannot
|
||||
be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>+
|
||||
or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> + <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_plus<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator + (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> + <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_plus<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_plus<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -113,68 +113,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">+=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">+=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_plus_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_plus_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">+=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator+=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">+=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_plus_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_plus_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_plus_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_plus_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> += <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">+=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">+=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_plus_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_plus_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>+=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>+=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_plus_assign<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_plus_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>+= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> += <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_plus_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator += (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> += <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_plus_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_plus_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -119,68 +119,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">>></span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">>></span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_right_shift</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_right_shift</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">>></span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>>(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator>>(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>>(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">>></span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_right_shift</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_right_shift.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_right_shift
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_right_shift<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">>>(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T> <span class="keyword">operator</span> >> <span class="special">(</span>const <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">>></span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">>></span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_right_shift<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_right_shift<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>>>
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>>>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_right_shift<Lhs></code> will
|
||||
produce a compiler error. For this reason <code class="literal">has_right_shift</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>>> or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A <span class="keyword">operator</span> >> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_right_shift<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator >> (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A <span class="keyword">operator</span> >> <span class="special">(</span>const <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_right_shift<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_right_shift<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
@@ -111,68 +111,81 @@
|
||||
<p>
|
||||
<span class="bold"><strong>Known issues:</strong></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span><span class="special">>>=</span></code> is public or not: if <code class="computeroutput"><span class="keyword">operator</span><span class="special">>>=</span></code>
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="computeroutput"><span class="identifier">has_right_shift_assign</span><span class="special"><</span><span class="identifier">Lhs</span><span class="special">></span></code> will produce a compiler error. For
|
||||
this reason <code class="computeroutput"><span class="identifier">has_right_shift_assign</span></code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span><span class="special">>>=</span></code>
|
||||
or not.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>>=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator>>=(const A&) is private</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">>>=(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift_assign</span><span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift_assign</span><span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
There is an issue when applying this trait to template classes. If <code class="computeroutput"><span class="keyword">operator</span><span class="special">>>=</span></code>
|
||||
is defined but does not bind for a given template type, it is still detected
|
||||
by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
|
||||
instead of <code class="computeroutput"><span class="keyword">false</span></code>. Example:
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_right_shift_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<p>
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and
|
||||
decltype/declval) this trait offers near perfect detection. In this situation
|
||||
the macro <code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
will be defined after including <code class="literal"><boost/type_traits/has_right_shift_assign.hpp></code>.
|
||||
Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then has_right_shift_assign
|
||||
cannot perform introspection of the template function body to ensure that
|
||||
the type meets all of the conceptual requirements of the actual code.
|
||||
</p>
|
||||
<p>
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span>has_right_shift_assign<span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">contains</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span>
|
||||
<span class="identifier">contains</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">d</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">(</span><span class="identifier">d</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">>>=(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
contains<T>& <span class="keyword">operator</span> >>= <span class="special">(</span><span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
<span class="identifier">good</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/*something*/</span><span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">>>=</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_right_shift_assign</span><span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">>>=</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
|
||||
<span class="comment">// works fine for contains<good></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_right_shift_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">good</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">good</span><span class="special">></span> <span class="identifier">g</span><span class="special">;</span>
|
||||
<span class="identifier">g</span><span class="special">&</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
|
||||
<span class="comment">// does not work for contains<bad></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special"><<</span><span class="identifier">boost</span><span class="special">::</span>has_right_shift_assign<span class="special"><</span> <span class="identifier">contains</span><span class="special"><</span> <span class="identifier">bad</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">value</span><span class="special"><<</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
|
||||
<span class="identifier">contains</span><span class="special"><</span><span class="identifier">bad</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span>
|
||||
<span class="identifier">b</span><span class="special">&</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
|
||||
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<p>
|
||||
For older compilers (<code class="computeroutput"><span class="identifier">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></code>
|
||||
not defined) then there are a number of issues:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
This trait cannot detect whether binary <code class="computeroutput"><span class="keyword">operator</span></code>>>=
|
||||
is public or not: if <code class="computeroutput"><span class="keyword">operator</span></code>>>=
|
||||
is defined as a private member of <code class="computeroutput"><span class="identifier">Lhs</span></code>
|
||||
then instantiating <code class="literal">has_right_shift_assign<Lhs></code>
|
||||
will produce a compiler error. For this reason <code class="literal">has_right_shift_assign</code>
|
||||
cannot be used to determine whether a type has a public <code class="computeroutput"><span class="keyword">operator</span></code>>>= or not.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> A& <span class="keyword">operator</span> >>= <span class="special">(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_right_shift_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator >>= (const A&) is private</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
|
||||
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
|
||||
In this case, the compiler will report an ambiguous overload.
|
||||
</li></ul></div>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
|
||||
A& <span class="keyword">operator</span> >>= <span class="special">(</span><span class="identifier">A</span><span class="special">&,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&);</span>
|
||||
<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_right_shift_assign<span class="special"><</span><span class="identifier">A</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span>has_right_shift_assign<span class="special"><</span><span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload</span>
|
||||
</pre>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is not
|
||||
properly handled and would lead to undefined behavior
|
||||
</li>
|
||||
</ul></div>
|
||||
</li></ul></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
|
||||
+1
-29
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="id1670677"></a>Class Index</h2></div></div></div>
|
||||
<a name="id1658358"></a>Class Index</h2></div></div></div>
|
||||
<p><a class="link" href="s11.html#idx_id_0">A</a> <a class="link" href="s11.html#idx_id_2">C</a> <a class="link" href="s11.html#idx_id_3">D</a> <a class="link" href="s11.html#idx_id_4">E</a> <a class="link" href="s11.html#idx_id_5">F</a> <a class="link" href="s11.html#idx_id_6">H</a> <a class="link" href="s11.html#idx_id_7">I</a> <a class="link" href="s11.html#idx_id_8">M</a> <a class="link" href="s11.html#idx_id_9">N</a> <a class="link" href="s11.html#idx_id_10">O</a> <a class="link" href="s11.html#idx_id_11">P</a> <a class="link" href="s11.html#idx_id_12">R</a> <a class="link" href="s11.html#idx_id_13">T</a></p>
|
||||
<div class="variablelist"><dl class="variablelist">
|
||||
<dt>
|
||||
@@ -358,42 +358,14 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">trait</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">has_bit_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">has_bit_and_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">has_bit_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">has_bit_or_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">has_bit_xor</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">has_bit_xor_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_complement.html" title="has_complement"><span class="index-entry-level-1">has_complement</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_dereference.html" title="has_dereference"><span class="index-entry-level-1">has_dereference</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">has_divides</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">has_divides_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">has_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">has_greater</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">has_greater_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">has_left_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">has_left_shift_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">has_less</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">has_less_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">has_logical_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_not.html" title="has_logical_not"><span class="index-entry-level-1">has_logical_not</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">has_logical_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">has_minus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">has_minus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">has_modulus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">has_modulus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">has_multiplies</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">has_multiplies_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_negate.html" title="has_negate"><span class="index-entry-level-1">has_negate</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">has_not_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">has_plus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">has_plus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_post_decrement.html" title="has_post_decrement"><span class="index-entry-level-1">has_post_decrement</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_post_increment.html" title="has_post_increment"><span class="index-entry-level-1">has_post_increment</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_pre_decrement.html" title="has_pre_decrement"><span class="index-entry-level-1">has_pre_decrement</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_pre_increment.html" title="has_pre_increment"><span class="index-entry-level-1">has_pre_increment</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">has_right_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">has_right_shift_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_unary_minus.html" title="has_unary_minus"><span class="index-entry-level-1">has_unary_minus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_unary_plus.html" title="has_unary_plus"><span class="index-entry-level-1">has_unary_plus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/category/value_traits/operators.html" title="Operator Type Traits"><span class="index-entry-level-1">Operator Type Traits</span></a></p></li>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="id1672702"></a>Typedef Index</h2></div></div></div>
|
||||
<a name="id1662618"></a>Typedef Index</h2></div></div></div>
|
||||
<p><a class="link" href="s12.html#idx_id_21">F</a> <a class="link" href="s12.html#idx_id_28">R</a> <a class="link" href="s12.html#idx_id_29">T</a> <a class="link" href="s12.html#idx_id_31">V</a></p>
|
||||
<div class="variablelist"><dl class="variablelist">
|
||||
<dt>
|
||||
|
||||
+34
-1
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="id1672913"></a>Macro Index</h2></div></div></div>
|
||||
<a name="id1662800"></a>Macro Index</h2></div></div></div>
|
||||
<p><a class="link" href="s13.html#idx_id_33">B</a></p>
|
||||
<div class="variablelist"><dl class="variablelist">
|
||||
<dt>
|
||||
@@ -164,6 +164,39 @@
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">has_bit_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">has_bit_and_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">has_bit_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">has_bit_or_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">has_bit_xor</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">has_bit_xor_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">has_divides</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">has_divides_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">has_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">has_greater</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">has_greater_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">has_left_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">has_left_shift_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">has_less</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">has_less_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">has_logical_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">has_logical_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">has_minus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">has_minus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">has_modulus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">has_modulus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">has_multiplies</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">has_multiplies_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">has_not_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">has_plus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">has_plus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">has_right_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">has_right_shift_assign</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; "><li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/is_class.html" title="is_class"><span class="index-entry-level-1">is_class</span></a></p></li></ul></div>
|
||||
</li>
|
||||
|
||||
+62
-57
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="id1673613"></a>Index</h2></div></div></div>
|
||||
<a name="id1661483"></a>Index</h2></div></div></div>
|
||||
<p><a class="link" href="s14.html#idx_id_48">A</a> <a class="link" href="s14.html#idx_id_49">B</a> <a class="link" href="s14.html#idx_id_50">C</a> <a class="link" href="s14.html#idx_id_51">D</a> <a class="link" href="s14.html#idx_id_52">E</a> <a class="link" href="s14.html#idx_id_53">F</a> <a class="link" href="s14.html#idx_id_54">H</a> <a class="link" href="s14.html#idx_id_55">I</a> <a class="link" href="s14.html#idx_id_56">M</a> <a class="link" href="s14.html#idx_id_57">N</a> <a class="link" href="s14.html#idx_id_58">O</a> <a class="link" href="s14.html#idx_id_59">P</a> <a class="link" href="s14.html#idx_id_60">R</a> <a class="link" href="s14.html#idx_id_61">T</a> <a class="link" href="s14.html#idx_id_62">U</a> <a class="link" href="s14.html#idx_id_63">V</a></p>
|
||||
<div class="variablelist"><dl class="variablelist">
|
||||
<dt>
|
||||
@@ -195,6 +195,39 @@
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">has_bit_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">has_bit_and_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">has_bit_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">has_bit_or_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">has_bit_xor</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">has_bit_xor_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">has_divides</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">has_divides_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">has_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">has_greater</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">has_greater_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">has_left_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">has_left_shift_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">has_less</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">has_less_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">has_logical_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">has_logical_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">has_minus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">has_minus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">has_modulus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">has_modulus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">has_multiplies</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">has_multiplies_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">has_not_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">has_plus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">has_plus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">has_right_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">has_right_shift_assign</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; "><li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/is_class.html" title="is_class"><span class="index-entry-level-1">is_class</span></a></p></li></ul></div>
|
||||
</li>
|
||||
@@ -308,49 +341,49 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_bit_and</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">has_bit_and</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_bit_and_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">has_bit_and_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_bit_or</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">has_bit_or</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_bit_or_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">has_bit_or_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_bit_xor</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">has_bit_xor</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_bit_xor_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">has_bit_xor_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
@@ -372,82 +405,82 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_divides</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">has_divides</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_divides_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">has_divides_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_equal_to</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">has_equal_to</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/category/value_traits/operators.html" title="Operator Type Traits"><span class="index-entry-level-1">Operator Type Traits</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_greater</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">has_greater</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_greater_equal</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">has_greater_equal</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_left_shift</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">has_left_shift</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_left_shift_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">has_left_shift_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_less</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">has_less</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_less_equal</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">has_less_equal</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_logical_and</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">has_logical_and</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
@@ -461,57 +494,57 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_logical_or</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">has_logical_or</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_minus</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">has_minus</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_minus_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">has_minus_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_modulus</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">has_modulus</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_modulus_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">has_modulus_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_multiplies</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">has_multiplies</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_multiplies_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">has_multiplies_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
@@ -558,9 +591,9 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_not_equal_to</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">has_not_equal_to</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
@@ -570,17 +603,17 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_plus</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">has_plus</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_plus_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">has_plus_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
@@ -618,17 +651,17 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_right_shift</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">has_right_shift</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">has_right_shift_assign</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">dont_care</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">has_right_shift_assign</span></a></strong></span></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">trait</span></a></p></li>
|
||||
</ul></div>
|
||||
</li>
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
@@ -982,42 +1015,14 @@
|
||||
<li class="listitem" style="list-style-type: none">
|
||||
<p><span class="index-entry-level-0">trait</span></p>
|
||||
<div class="index"><ul class="index" style="list-style-type: none; ">
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and.html" title="has_bit_and"><span class="index-entry-level-1">has_bit_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_and_assign.html" title="has_bit_and_assign"><span class="index-entry-level-1">has_bit_and_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or.html" title="has_bit_or"><span class="index-entry-level-1">has_bit_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_or_assign.html" title="has_bit_or_assign"><span class="index-entry-level-1">has_bit_or_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor.html" title="has_bit_xor"><span class="index-entry-level-1">has_bit_xor</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><span class="index-entry-level-1">has_bit_xor_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_complement.html" title="has_complement"><span class="index-entry-level-1">has_complement</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_dereference.html" title="has_dereference"><span class="index-entry-level-1">has_dereference</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides.html" title="has_divides"><span class="index-entry-level-1">has_divides</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_divides_assign.html" title="has_divides_assign"><span class="index-entry-level-1">has_divides_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_equal_to.html" title="has_equal_to"><span class="index-entry-level-1">has_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater.html" title="has_greater"><span class="index-entry-level-1">has_greater</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_greater_equal.html" title="has_greater_equal"><span class="index-entry-level-1">has_greater_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift.html" title="has_left_shift"><span class="index-entry-level-1">has_left_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_left_shift_assign.html" title="has_left_shift_assign"><span class="index-entry-level-1">has_left_shift_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less.html" title="has_less"><span class="index-entry-level-1">has_less</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_less_equal.html" title="has_less_equal"><span class="index-entry-level-1">has_less_equal</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_and.html" title="has_logical_and"><span class="index-entry-level-1">has_logical_and</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_not.html" title="has_logical_not"><span class="index-entry-level-1">has_logical_not</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_logical_or.html" title="has_logical_or"><span class="index-entry-level-1">has_logical_or</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus.html" title="has_minus"><span class="index-entry-level-1">has_minus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_minus_assign.html" title="has_minus_assign"><span class="index-entry-level-1">has_minus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus.html" title="has_modulus"><span class="index-entry-level-1">has_modulus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_modulus_assign.html" title="has_modulus_assign"><span class="index-entry-level-1">has_modulus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies.html" title="has_multiplies"><span class="index-entry-level-1">has_multiplies</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_multiplies_assign.html" title="has_multiplies_assign"><span class="index-entry-level-1">has_multiplies_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_negate.html" title="has_negate"><span class="index-entry-level-1">has_negate</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_not_equal_to.html" title="has_not_equal_to"><span class="index-entry-level-1">has_not_equal_to</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus.html" title="has_plus"><span class="index-entry-level-1">has_plus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_plus_assign.html" title="has_plus_assign"><span class="index-entry-level-1">has_plus_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_post_decrement.html" title="has_post_decrement"><span class="index-entry-level-1">has_post_decrement</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_post_increment.html" title="has_post_increment"><span class="index-entry-level-1">has_post_increment</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_pre_decrement.html" title="has_pre_decrement"><span class="index-entry-level-1">has_pre_decrement</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_pre_increment.html" title="has_pre_increment"><span class="index-entry-level-1">has_pre_increment</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift.html" title="has_right_shift"><span class="index-entry-level-1">has_right_shift</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_right_shift_assign.html" title="has_right_shift_assign"><span class="index-entry-level-1">has_right_shift_assign</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_unary_minus.html" title="has_unary_minus"><span class="index-entry-level-1">has_unary_minus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/reference/has_unary_plus.html" title="has_unary_plus"><span class="index-entry-level-1">has_unary_plus</span></a></p></li>
|
||||
<li class="listitem" style="list-style-type: none"><p><a class="link" href="../boost_typetraits/category/value_traits/operators.html" title="Operator Type Traits"><span class="index-entry-level-1">Operator Type Traits</span></a></p></li>
|
||||
|
||||
@@ -158,6 +158,74 @@
|
||||
[template all_compilers[] __compat All current compilers are supported by this trait.]
|
||||
[template has_binary_operator_compat[] __compat Requires working SFINAE (i.e. BOOST_NO_SFINAE is not set). Only a minority of rather old compilers do not support this.]
|
||||
|
||||
[template binary_operator_known_issues[Name Op Ret1 Ret2 Const]
|
||||
[*Known issues:]
|
||||
|
||||
For modern compilers (those that support arbitrary SFINAE-expressions and decltype/declval) this trait offers near perfect detection.
|
||||
In this situation the macro `BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION` will be defined after including
|
||||
[^<boost/type_traits/[Name].hpp>]. Please note however, that detection is based on function signature only,
|
||||
in the case that the operator is a function template then [Name] cannot perform
|
||||
introspection of the template function body to ensure that the type meets all of the conceptual requirements of the actual code.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
#include <boost/type_traits/``[Name]``.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
struct contains
|
||||
{
|
||||
T data;
|
||||
contains(const T& d) : data(d) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
``[Ret2]`` operator ``[Op]`` (``[Const]``contains<T> &lhs, const contains<T> &rhs) {
|
||||
return f(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
class bad { };
|
||||
class good { };
|
||||
good f(const good&, const good&) { return /*something*/; }
|
||||
|
||||
int main() {
|
||||
std::cout<<std::boolalpha;
|
||||
// works fine for contains<good>
|
||||
std::cout<<boost::``[Name]``< contains< good > >::value<<'\n'; // true
|
||||
contains<good> g;
|
||||
g&g; // ok
|
||||
// does not work for contains<bad>
|
||||
std::cout<<boost::``[Name]``< contains< bad > >::value<<'\n'; // true, should be false
|
||||
contains<bad> b;
|
||||
b&b; // compile time error
|
||||
return 0;
|
||||
}
|
||||
|
||||
For older compilers (`BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION` not defined) then there are a number of issues:
|
||||
|
||||
* This trait cannot detect whether binary `operator`[Op] is public or not:
|
||||
if `operator`[Op] is defined as a private member of `Lhs` then
|
||||
instantiating [^[Name]<Lhs>] will produce a compiler error.
|
||||
For this reason [^[Name]] cannot be used to determine whether a type has a public `operator`[Op] or not.
|
||||
|
||||
struct A { private: ``[Ret1]`` operator ``[Op]`` (const A&); };
|
||||
boost::``[Name]``<A>::value; // error: A::operator ``[Op]`` (const A&) is private
|
||||
|
||||
|
||||
* There is an issue if the operator exists only for type `A` and `B` is
|
||||
convertible to `A`. In this case, the compiler will report an ambiguous overload.
|
||||
|
||||
struct A { };
|
||||
``[Ret1]`` operator ``[Op]`` (``[Const]``A&, const A&);
|
||||
struct B { operator A(); };
|
||||
boost::``[Name]``<A>::value; // this is fine
|
||||
boost::``[Name]``<B>::value; // error: ambiguous overload
|
||||
|
||||
|
||||
* `volatile` qualifier is not properly handled and would lead to undefined behavior
|
||||
]
|
||||
|
||||
|
||||
A printer-friendly [@http://sourceforge.net/projects/boost/files/boost-docs/
|
||||
PDF version of this manual is also available].
|
||||
|
||||
Reference in New Issue
Block a user