return … или return (…)

231
26 ноября 2016, 18:58

Часто вижу, что выражение, которое возвращает return, заключено в круглые скобки. Например, в хедере set в Visual Studio 2015 во всех функциях, возвращающих ссылку на множество, прописано return (*this).

Какие плюсы есть у такого стиля, ведь, например, эти две функции отличаются в том же VC++?

decltype(auto) f1()
{
    int i{};
    return (i); // возвращает int&
}
decltype(auto) f2()
{
    int i{};
    return i; // возвращает int
}
Answer 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

Можете заглянуть в эту тему, где в конце нее я писал про различные способы инициализации.:)

Answer 2

Нет никаких плюсов. Это любо причудливый стиль кодирования отдельных компаний, либо же результат работы автогенератора, в котором, возможно, произведение подобного результата оправдано какими-то причинами.

Как Вы сами заметили в вопросе, разница появилась лишь в C++14 и, на мой взгляд, является чисто академической.

Answer 3

Из скобок можно получить интересный хак (говорят, не по стандарту, но везде работает):

http://ideone.com/tHyYhE

#include <cstdio>
int 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 - это не функция.

READ ALSO
Эхо сервер на двух разных машинах, подключенных к одному wifi с\с++

Эхо сервер на двух разных машинах, подключенных к одному wifi с\с++

Есть две машины на Linux, подключённые к одному Wi-Fi роутеруНужно реализовать на них эхо-сервер на C\C++

228
варианты инициализации объектов

варианты инициализации объектов

Начал изучать c++Может кто подробно объяснить чем отличаются эти варианты инициализации? Когда что вызывается и т

265
ifstream проход по строке

ifstream проход по строке

Просто есть строка string, в ней слова, разделенные пробеламиКак пройтись по этой строке, поочередно занося в буфер эти слова

254
Как вставит строку внутрь другой строки при нахождении определенного символа

Как вставит строку внутрь другой строки при нахождении определенного символа

Есть символ С и строки S1, S2Перед каждым входжением символа С в строку S1 нужно вставить строку S2

336