Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

has_bit_and

template <class Lhs, class Rhs=Lhs, class Ret=dont_care>
struct has_bit_and : public true_type-or-false_type {};

Inherits: If (i) lhs of type Lhs and rhs of type Rhs can be used in expression lhs&rhs, and (ii) Ret=dont_care or the result of expression lhs&rhs is convertible to Ret then inherits from true_type, otherwise inherits from false_type.

The default behaviour (Ret=dont_care) is to not check for the return value of binary operator&. If Ret is different from the default dont_care type, the return value is checked to be convertible to Ret. Convertible to Ret means that the return value of the operator can be used as argument to a function expecting Ret:

void f(Ret);
Lhs lhs;
Rhs rhs;
f(lhs&rhs); // is valid if has_bit_and<Lhs, Rhs, Ret>::value==true

If Ret=void, the return type is checked to be exactly void.

Header: #include <boost/type_traits/has_bit_and.hpp> or #include <boost/type_traits/has_operator.hpp> or #include <boost/type_traits.hpp>

Examples:

has_bit_and<Lhs, Rhs, Ret>::value_type is the type bool.

has_bit_and<Lhs, Rhs, Ret>::value is a bool integral constant expression.

has_bit_and<int>::value is a bool integral constant expression that evaluates to true.

has_bit_and<long> inherits from true_type.

has_bit_and<int, int, int> inherits from true_type.

has_bit_and<const int, int> inherits from true_type.

has_bit_and<int, double, bool> inherits from false_type.

has_bit_and<int, int, std::string> inherits from false_type.

See also: Operator Type Traits

Compiler Compatibility: Requires working SFINAE (i.e. BOOST_NO_SFINAE is not set). Only a minority of rather old compilers do not support this.

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/has_bit_and.hpp>. 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.

Example:

#include <boost/type_traits/has_bit_and.hpp>
#include <iostream>

template <class T>
struct contains
{
   T data;
   contains(const T& d) : data(d) {}
};

template <class T>
contains<T> operator & (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::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;
}

For older compilers (BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION not defined) then there are a number of issues:

struct A { private: A operator & (const A&); };
boost::has_bit_and<A>::value; // error: A::operator & (const A&) is private
struct A { };
A 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

PrevUpHomeNext