[/ (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_pre_increment has_pre_increment] template struct has_pre_increment : 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_pre_increment::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_pre_increment::value_type` is the type `bool`.] [:`has_pre_increment::value` is a `bool` integral constant expression.] [:`has_pre_increment::value` is a `bool` integral constant expression that evaluates to `true`.] [:`has_pre_increment` inherits from `__true_type`.] [:`has_pre_increment` inherits from `__true_type`.] [:`has_pre_increment` inherits from `__true_type`.] [:`has_pre_increment` inherits from `__true_type`.] [:`has_pre_increment` inherits from `__true_type`.] [:`has_pre_increment` inherits from `__true_type`.] [:`has_pre_increment` inherits from `__false_type`.] [:`has_pre_increment` inherits from `__false_type`.] [:`has_pre_increment` 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_pre_increment` will produce a compiler error. For this reason `has_pre_increment` cannot be used to determine whether a type has a public `operator++` or not. `` struct A { private: void operator++(); }; boost::has_pre_increment::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_pre_increment::value; // this is fine boost::has_pre_increment::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 [prefix_operator_known_issues has_pre_increment..++] [endsect]