Зачем нужна конструкция decltype(auto) при возврате из функции, если можно писать auto?
Ответы
Ответ 1
auto это "усохший" (decayed) тип выражения, т.е. теряются ссылки и происходит копирование:
string& f();
auto x = f(); // тип x - string, ссылка потерялась, строка скопировалась
auto g() { return f(); } // возвращается string
// аналог в С++11: auto g() -> decay::type;
decltype(expr) - это фактический тип выражения, без усыханий.
decltype(auto) - это удобный синтаксис, который позволяет не писать выражение внутри decltype.
decltype(auto) y = f(); // тип y - string&
// аналог в С++11: decltype(f()) y = f();
decltype(auto) h() { return f(); } // возвращается string&
// аналог в С++11: auto h() -> decltype(f());
Другими словами, decltype(auto) это удобная замена decltype(expr),
а auto это короткий синтаксис для std::decay::type.
Ответ 2
auto
В С++11 ключевое слово auto лишено своего первоначального смысла в качестве спецификатор
класса хранения и теперь применяется для реализации автоматического выведения типа при условии, что задан явный инициализатор. Компилятор устанавливает тип переменной в тип инициализирующего значения:
auto maton = 112; // maton получает тип int
auto pt = &maton; // pt получает тип int *
double fm(double, int);
auto pf = fm; // pf получает тип double (*) (double, int)
Ключевое слово auto может также упростить объявления шаблонов. Например, если і
является объектом типа std::initializer_list, следующий код
for (std::initializer_list::iterator p = il.begin();
p !=il.end(); p++)
можно заменить таким:
for (auto p = il.begin(); p != il.end(); p++)
decltype
Ключевое слово decltype создает переменную типа, который указан выражением. Приведенны
ниже оператор означает "назначить у тот же самый тип, что х", где х представляет собой выражение:
decltype(х) у;
Вот еще пара примеров:
double x;
int n;
decltype(x*n) q; // q получает тот же тип, что и х*n, т.е. double
decltype(&x) pd; // pd получает тот же тип, что и &х, т.е. double *
Это особенно полезно в определениях шаблонов, когда тип может быть не определе
вплоть до создания специфического экземпляра:
template double; // новый синтаксис, // возвращаемым типом является double
Новый синтаксис может выглядеть менее читабельным, чем традиционные объявления функций
однако он делает возможным использование decltype для указания возвращаемых типов шаблонных функций:
template decltype (T*U)
{
}
Иллюстрируемая здесь проблема состоит в том, что когда компилятор читает списо
параметров ef f, Т и U не находятся в области видимости, поэтому любое использование decltype должно находиться после этого списка параметров. Новый синтаксис делает это возможным.
Комментариев нет:
Отправить комментарий