Просвещение Использование С++ 11 decltype
Я только что видел этот действительно приятный разговор Rock Hard: С++ Evolution Борис Джабес. В разделе разговора о программировании на высшем заказе он говорит, что следующее является примером функции, более общей по отношению к ее возвращаемому типу, и приводит к меньшему числу перегрузок функций шаблона
template <typename Func>
auto deduce(const Func & f) -> decltype(f())
{..}
Это может быть реализовано с использованием простого синтаксиса шаблона следующим образом
template <typename Func>
Func deduce(const Func & f)
{..}
поэтому я думаю, что выбранный пример действительно не показывает уникальную мощность decltype
. Может ли кто-нибудь привести пример такого более просветительного использования decltype
?
Ответы
Ответ 1
Ваши подозрения неверны.
void f() { }
Теперь deduce(&f)
имеет тип void
, но с вашим переписанием он имеет тип void(*)()
. В любом случае, везде, где вы хотите получить тип выражения или декларации, вы используете decltype
(обратите внимание на тонкую разницу между этими двумя. decltype(x)
не обязательно совпадает с decltype((x))
).
Например, вероятно, что ваша реализация стандартной библиотеки где-то содержит строки типа
using size_t = decltype(sizeof(0));
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
Поиск правильного типа возврата add
является сложной проблемой на протяжении всего С++. Теперь это простое упражнение.
template<typename A, typename B>
auto add(A const& a, B const& b) -> decltype(a + b) { return a + b; }
Мало известно, что вы можете использовать decltype
до ::
и в псевдо-деструкторе name
// has no effect
(0).~decltype(0)();
// it and ite will be iterators into an initializer list
auto x = { 1, 2, 3 };
decltype(x)::iterator it = x.begin(), ite = x.end();
Ответ 2
std::for_each(c.begin(), c.end(), [](decltype (c.front()) val){val*=2;});
Автообновление параметра value_type контейнера c не может быть выполнено без decltype.
Ответ 3
Одно место, в котором я его использую, - это то, где мне нужно создать переменную, которая должна иметь тот же тип другой переменной. но я не уверен, что в будущем тип останется таким же или нет.
void foo(int a)//maybe in future type of a changed
{
decltype(a) b;
//do something with b
}