Brian Silverman | 60e3e2a | 2018-08-04 23:57:12 -0700 | [diff] [blame^] | 1 | [/ |
| 2 | / Copyright (c) 2008 Howard Hinnant |
| 3 | / Copyright (c) 2009-20012 Vicente J. Botet Escriba |
| 4 | / |
| 5 | / Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 6 | / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 7 | /] |
| 8 | |
| 9 | [article Declval |
| 10 | [quickbook 1.5] |
| 11 | [authors [Hinnant, Howard]] |
| 12 | [authors [Botet Escriba, Vicente J.]] |
| 13 | [copyright 2008 Howard Hinnant] |
| 14 | [copyright 2009-2012 Vicente J. Botet Escriba] |
| 15 | [license |
| 16 | Distributed under the Boost Software License, Version 1.0. |
| 17 | (See accompanying file LICENSE_1_0.txt or copy at |
| 18 | [@http://www.boost.org/LICENSE_1_0.txt]) |
| 19 | ] |
| 20 | ] |
| 21 | |
| 22 | [/===============] |
| 23 | [section Overview] |
| 24 | [/===============] |
| 25 | |
| 26 | The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958: |
| 27 | Moving Swap Forward]. Here follows a rewording of this chapter. |
| 28 | |
| 29 | With the provision of decltype, late-specified return types, and default template-arguments for function templates a |
| 30 | new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale. |
| 31 | Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration |
| 32 | |
| 33 | template<class T> |
| 34 | T&& declval(); // not used |
| 35 | |
| 36 | as part of the function template declaration |
| 37 | |
| 38 | template<class To, class From> |
| 39 | decltype(static_cast<To>(declval<From>())) convert(From&&); |
| 40 | |
| 41 | or as part of a class template definition |
| 42 | |
| 43 | template<class> class result_of; |
| 44 | |
| 45 | template<class Fn, class... ArgTypes> |
| 46 | struct result_of<Fn(ArgTypes...)> |
| 47 | { |
| 48 | typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type; |
| 49 | }; |
| 50 | |
| 51 | The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function. |
| 52 | The name is supposed to direct the reader's attention to the fact that the expression `declval<T>()` is an lvalue if and only if |
| 53 | T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to |
| 54 | |
| 55 | template<class T> |
| 56 | typename std::add_rvalue_reference<T>::type declval(); // not used |
| 57 | |
| 58 | which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()` |
| 59 | already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard. |
| 60 | |
| 61 | The provision of a new library component that allows the production of values in unevaluated expressions is considered |
| 62 | important to realize constrained templates in C++0x where concepts are not available. |
| 63 | This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer. |
| 64 | |
| 65 | [endsect] |
| 66 | |
| 67 | |
| 68 | [/=================] |
| 69 | [section:reference Reference ] |
| 70 | [/=================] |
| 71 | |
| 72 | `#include <boost/utility/declval.hpp>` |
| 73 | |
| 74 | namespace boost { |
| 75 | |
| 76 | template <typename T> |
| 77 | typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand |
| 78 | |
| 79 | } // namespace boost |
| 80 | |
| 81 | |
| 82 | The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. |
| 83 | |
| 84 | template <typename T> |
| 85 | typename add_rvalue_reference<T>::type declval(); |
| 86 | |
| 87 | [*Remarks:] If this function is used, the program is ill-formed. |
| 88 | |
| 89 | [*Remarks:] The template parameter T of declval may be an incomplete type. |
| 90 | |
| 91 | [*Example:] |
| 92 | |
| 93 | template <class To, class From> |
| 94 | decltype(static_cast<To>(declval<From>())) convert(From&&); |
| 95 | |
| 96 | Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To. |
| 97 | |
| 98 | [endsect] |
| 99 | |
| 100 | [/===============] |
| 101 | [section History] |
| 102 | [/===============] |
| 103 | |
| 104 | [heading boost 1.50] |
| 105 | |
| 106 | Fixes: |
| 107 | |
| 108 | * [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval. |
| 109 | |
| 110 | [endsect] |
| 111 | |
| 112 | |
| 113 | |
| 114 | |