Просвещение Использование C ++ 11 decltype - PullRequest
13 голосов
/ 02 октября 2011

Я только что видел этот действительно хороший разговор Rock Hard: C ++ Evolving Бориса Ябеса.В разделе доклада о родовом программировании высшего порядка он говорит, что ниже приведен пример функции, которая является более общей по отношению к типу возвращаемого значения и приводит к уменьшению перегрузок шаблонных функций

template <typename Func>
auto deduce(const Func & f) -> decltype(f())
{..}

Это, однако, может быть реализовано с использованием простого синтаксиса шаблона следующим образом

template <typename Func>
Func deduce(const Func & f)
{..}

, поэтому я думаю, что выбранный пример не действительно показывает уникальную силу decltype.Кто-нибудь может привести пример такого более просветляющего использования decltype?

Ответы [ 3 ]

26 голосов
/ 02 октября 2011

Ваши подозрения неверны.

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 было сложной проблемой на протяжении всего C ++. Теперь это простое упражнение.

template<typename A, typename B> 
auto add(A const& a, B const& b) -> decltype(a + b) { return a + b; }

Малоизвестно, что вы можете использовать decltype до :: и в псевдодеструкторном имени

// 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();
1 голос
/ 02 октября 2011
std::for_each(c.begin(), c.end(), [](decltype (c.front()) val){val*=2;});

Автоопределение value_type контейнера c невозможно без decltype .

0 голосов
/ 08 июня 2014

В одном месте, где я его использую, мне нужно создать переменную, которая должна иметь такой же тип, что и другая переменная. но я не уверен, что в будущем тип останется таким же или нет.

void foo(int a)//maybe in future type of a changed
{
    decltype(a) b;
    //do something with b
}
...