Ключевые слова auto и decltype – сходства, отличия и нюансы использования. Часть 4. Новое в С++14/17 по auto и decltype.


Добавлено в С++14

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

auto add(int a, int b)
{
     return a + b;
}

вместо

int add(int a, int b)
{
      return a + b;
}

Изменение правила вывода типа при объявлении переменной. Как мы уже поняли, пути по которым auto и decltype выводят тип выражения существенно отличаются. В С++14 мы имеем возможность использовать правила вывода decltype при инициализации переменной.


int& foo();
decltype(auto) i = foo(); // i типа int&


Если бы мы использовали здесь auto – мы получили бы int вместо int&:

int& foo();
auto i = f(); // i
типа int


Разумеется, мы могли бы также получить int&, добавив ключевое слово auto со ссылкой:

int& foo();
auto& i = f(); // i типа int& 

Вывод типа аргументов лямбда означает, что теперь вы можете использовать ключевое слово auto вместо фактического типа, когда объявляете параметр лямбда-функции:

[](auto x, auto y) {return x + y;};
То, что мы здесь видим - это обобщенная лямбда. Таким образом, можно сказать, что классы и функции используют синтаксис шаблона для достижения универсальности, в то время как лямбды используют ключевое слово auto для этой цели.

Добавлено в С++17

Добавлено две дополнительные функции ключевому слову auto[1].

Объявление параметра шаблона auto.

template<auto n>
auto f() -> std::pair<decltype(n), decltype(n)> //тип возвращаемого значения не может быть выведен из списка инициализации в фигурных скобках
{
    return {n, n};
}

Ключевое слово auto в шаблонном параметре может быть использовано для указания параметра, не являющегося типом, тип которого выводится из аргумента в точке инстанцирования. Это даёт более удобный путь для написания параметров вида:

template <typename Type, Type value>

Например,

template <typename Type, Type value> constexpr Type constant = value;
constexpr auto const IntConstant42 = constant<int, 42>;

может быть теперь выражено короче:

template <auto value> constexpr auto constant = value;
constexpr auto const IntConstant42 = constant<42>;

где вам нет необходимости указывать тип. Это возможность может быть использована и с вариативными шаблонными параметрами, например для реализации списка констант времени компиляции:

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;

template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {};
using MyList2 = HomogenousValueList<1, 2, 3>;


Структурированное связывание.

См. более раннюю мою статью тут 

Комментарии

Популярные сообщения из этого блога

Полезные новации С++17. Выражения свертки (Fold expressions)

Перегрузка и специализация шаблонных функций.

Поддержка декомпозиции при объявлении (structural bindings) для классов