[/ (C) Copyright 2009-2011 Frederic Bron. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). ] [section:has_negate has_negate] template struct has_negate : public __tof {}; __inherit If (i) `rhs` of type `Rhs` can be used in expression `-rhs`, and (ii) `Ret=dont_care` or the result of expression `-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 prefix `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); Rhs rhs; f(-rhs); // is valid if has_negate::value==true `` If `Ret=void`, the return type is checked to be exactly `void`. __header `#include ` or `#include ` or `#include ` [has_binary_operator_compat] __examples [:`has_negate::value_type` is the type `bool`.] [:`has_negate::value` is a `bool` integral constant expression.] [:`has_negate::value` is a `bool` integral constant expression that evaluates to `true`.] [:`has_negate` inherits from `__true_type`.] [:`has_negate` inherits from `__true_type`.] [:`has_negate` inherits from `__true_type`.] [:`has_negate` inherits from `__true_type`.] [:`has_negate` inherits from `__true_type`.] [:`has_negate` inherits from `__true_type`.] [:`has_negate` inherits from `__false_type`.] [*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits] [*Known issues:] * This trait cannot detect whether prefix `operator-` is public or not: if `operator-` is defined as a private member of `Rhs` then instantiating `has_negate` will produce a compiler error. For this reason `has_negate` cannot be used to determine whether a type has a public `operator-` or not. `` struct A { private: void operator-(); }; boost::has_negate::value; // error: A::operator-() 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&); struct B { operator A(); }; boost::has_negate::value; // this is fine boost::has_negate::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 #include template struct contains { T data; }; template bool operator-(const contains &rhs) { return f(rhs.data); } class bad { }; class good { }; bool f(const good&) { } int main() { std::cout< std::cout< >::value<<'\n'; // true contains g; -g; // ok // does not work for contains std::cout< >::value<<'\n'; // true, should be false contains b; -b; // compile time error return 0; } `` * `volatile` qualifier is not properly handled and would lead to undefined behavior [endsect]