Howard Hinnant
Vicente J. Botet Escriba
Copyright © 2008 Howard Hinnant
Copyright © 2009-2012 Vicente
J. Botet Escriba
Мотивация для деклавал
была введена в N2958: Moving Swap Forward. Ниже приводится переформулировка этой главы.
С предоставлением деклатипа, поздних типов возврата и аргументов шаблона по умолчанию для шаблонов функций появится новое поколение шаблонов SFINAE, чтобы по крайней мере частично компенсировать отсутствие концепций на временной шкале C++0x. Используя этот метод, иногда необходимо получить объект известного типа в неиспользующем контексте, например, с учетом декларации
template<class T>
T&& declval();
как часть декларации шаблона функции
template<class To, class From>
decltype(static_cast<To>(declval<From>())) convert(From&&);
или как часть определения шаблона класса
template<class> class result_of;
template<class Fn, class... ArgTypes>
struct result_of<Fn(ArgTypes...)>
{
typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type;
};
Роль шаблона функции declval() — преобразование типа T в значение без использования или оценки этой функции. Название должно направлять внимание читателя на то, что выражение declval<T>()
является lvalue тогда и только тогда, когда T является lvalue-ссылкой, иначе rvalue. Чтобы расширить область этой функции, мы можем сделать немного лучше, изменив ее заявление
template<class T>
typename std::add_rvalue_reference<T>::type declval();
это гарантирует, что мы также можем использовать cv void в качестве параметра шаблона. Внимательный читатель мог заметить, что declval()
уже существует под именем create() в рамках определения семантики типа trait is_convertible в стандарте C++0x.
Предоставление нового библиотечного компонента, позволяющего производить значения в неоцененных выражениях, считается важным для реализации ограниченных шаблонов в C++0x, где понятия недоступны. Ожидается, что эта чрезвычайно легкая функция будет частью ежедневного набора инструментов программиста C++0x.
#include <boost/utility/declvalhpp>
namespace boost {
template <typename T>
typename add_rvalue_reference<T>::type declval() noexcept;
}
Библиотека предоставляет деквал функционального шаблона для упрощения определения выражений, которые встречаются как неоцененные операнды.
template <typename T>
typename add_rvalue_reference<T>::type declval();
Замечания: Если эта функция используется, программа плохо сформирована.
Замечания: Параметр шаблона T деквала может быть неполным.
Пример:
template <class To, class From>
decltype(static_cast<To>(declval<From>())) convert(From&&);
Объявляет преобразование шаблона функций, которое участвует только в перегрузке, если тип From может быть явно преобразован в тип To.
Исправления:
- #6570 Добавление только для повышения::деклавал.