Начиная с C ++ 14, они часто бывают такими.
C ++ 14 добавляет дополнительный случай, когда круглые скобки вокруг возвращаемого значения могут изменить семантику. Этот фрагмент кода показывает две объявленные функции. Единственное отличие - круглые скобки вокруг возвращаемого значения.
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
В первом случае func1
возвращается значение, int
а во втором func1
- значение int&
. Разница в семантике напрямую связана с окружающими круглыми скобками .
Спецификатор auto
в его последней форме был введен в C ++ 11. В спецификации языка C ++ это описывается как:
Указывает, что тип объявляемой переменной будет автоматически выводиться из ее инициализатора. Для функций указывает, что возвращаемый тип является конечным возвращаемым типом или будет выводиться из его операторов возврата (начиная с C ++ 14).
Также в C ++ 11 появился decltype
спецификатор, описанный в спецификации языка C ++ :
Проверяет объявленный тип объекта или запрашивает возвращаемый тип выражения.
[вырезать]
Если аргумент является либо именем объекта / функции без скобок, либо выражением доступа к члену (object.member или pointer-> member), то decltype указывает объявленный тип сущности, указанной этим выражением.
Если аргумент - любое другое выражение типа T, то
а) если категория значения выражения - xvalue, то decltype указывает T &&
б) если категория значений выражения lvalue, то decltype указывает T &
c) в противном случае decltype указывает T
[вырезать]
Обратите внимание: если имя объекта заключено в скобки, оно становится выражением lvalue, поэтому decltype (arg) и decltype ((arg)) часто являются разными типами.
В C ++ 14 возможность использования decltype(auto)
была разрешена для типов, возвращаемых функцией. В исходных примерах проявляется семантическая разница в круглых скобках. Возвращаясь к исходным примерам:
int var1 = 42;
decltype(auto) func1() { return var1; } // return type is int, same as decltype(var1)
decltype(auto) func1() { return(var1); } // return type is int&, same as decltype((var1))
decltype(auto)
позволяет выводить конечный тип возвращаемого значения в функции из сущности / выражения в операторе возврата. В первой версии return var1;
это фактически то же самое, что и возврат типа decltype(var1)
( int
возвращаемый тип по правилу 1 выше), а во втором случае return (var1);
фактически то же самое, что и decltype((var1))
( int &
возвращаемый тип по правилу 2b).
Скобки делают возвращаемый тип int&
вместо int
, таким образом изменяя семантику. Мораль истории - «Не все круглые скобки в возвращаемом типе одинаковы».