Boost C++ Libraries Home Libraries People FAQ More

Declval

Howard Hinnant

Beman Dawes

Vicente J. Botet Escriba

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)


Table of Contents

Overview
Reference

The motivation for declval was introduced in N2958: Moving Swap Forward. Here follows a rewording of this chapter.

With the provision of decltype, late-specified return types, and default template-arguments for function templates a new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale. 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

template<class T>
T&& declval(); // not used

as part of the function template declaration

template<class To, class From>
decltype(static_cast<To>(declval<From>())) convert(From&&);

or as part of a class template definition

template<class> class result_of;

template<class Fn, class... ArgTypes>
struct result_of<Fn(ArgTypes...)> 
{
  typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type;
};

The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function. 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 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

template<class T>
typename std::add_rvalue_reference<T>::type declval(); // not used

which ensures that we can also use cv void as template parameter. The careful reader might have noticed that declval() 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.

The provision of a new library component that allows the production of values in unevaluated expressions is considered as important to realize constrained templates in C++0x where concepts are not available. This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer.

#include <boost/utility/declval.hpp>

namespace boost {

    template <typename T>
    typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand

}  // namespace boost

The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands.

template <typename T>
typename add_rvalue_reference<T>::type declval();

Remarks: If this function is used, the program is ill-formed.

Remarks: The template parameter T of declval may be an incomplete type.

Example:

template <class To, class From>
decltype(static_cast<To>(declval<From>())) convert(From&&);

Declares a function template convert which only participats in overloading if the type From can be explicitly converted to type To.

Last revised: September 16, 2010 at 16:19:10 GMT