#cpp
Часто вижу, что выражение, которое возвращает return, заключено в круглые скобки. Например, в хедере set в Visual Studio 2015 во всех функциях, возвращающих ссылку на множество, прописано return (*this). Какие плюсы есть у такого стиля, ведь, например, эти две функции отличаются в том же VC++? decltype(auto) f1() { int i{}; return (i); // возвращает int& } decltype(auto) f2() { int i{}; return i; // возвращает int }
Ответы
Ответ 1
Вопрос не о преимуществах, а о том, какой тип возвращаемого значения из функции вы хотите получить.:) Первая ваша функция имеет неопределенное поведение, так как возвращается ссылка на локальный объект функции, который прекратит свое существование после выхода из функции. Поэтому ссылка будет не действительной. Рассмотрите также следующий пример. Данная программа не будет компилироваться. int main() { int a[] = { 1, 2 }; decltype( auto ) b = a; } Здесь выражение в правой части, используемое для инициализации переменной b неявно преобразуется в указатель на первый элемент массива a. Тогла как эта программа int main() { int a[] = { 1, 2 }; decltype( auto ) b = ( a ); } успешно скомпилируется, и переменная b будет ссылкой на массив a, так как выражение ( a ) является lvalue. Согласно стандарту C++ (7.1.6.2 Simple type specifiers) 4 The type denoted by decltype(e) is defined as follows: — if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed; — otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e; — otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e; — otherwise, decltype(e) is the type of e. The operand of the decltype specifier is an unevaluated Можете заглянуть в эту тему, где в конце нее я писал про различные способы инициализации.:)Ответ 2
Нет никаких плюсов. Это любо причудливый стиль кодирования отдельных компаний, либо же результат работы автогенератора, в котором, возможно, произведение подобного результата оправдано какими-то причинами. Как Вы сами заметили в вопросе, разница появилась лишь в C++14 и, на мой взгляд, является чисто академической.Ответ 3
Из скобок можно получить интересный хак (говорят, не по стандарту, но везде работает): http://ideone.com/tHyYhE #includeint f(int x) { #define return(t) return (printf("%d => %d", x, t), t) if (x < 0) return (x * x); if (x > 0) return (-x); return (2*x + 4); #undef return } int main() { f(100); return 0; } Если есть скобки, то return становится кандидатом на подстановку макроса и можно, например, добавить логирование для отладки кода. Если же скобок нет, то подобный фокус не выйдет. Точнее, можно будет заменять сам return, но возвращаемое значение в макросе будет недоступно. Тем не менее, я за то, чтобы писать без скобок, поскольку это более естественно и прямолинейно. Всё-таки, return - это не функция.
Комментариев нет:
Отправить комментарий