Часто вижу, что выражение, которое возвращает return
, заключено в круглые скобки. Например, в хедере set
в Visual Studio 2015
во всех функциях, возвращающих ссылку на множество, прописано return (*this)
.
Какие плюсы есть у такого стиля, ведь, например, эти две функции отличаются в том же VC++
?
decltype(auto) f1()
{
int i{};
return (i); // возвращает int&
}
decltype(auto) f2()
{
int i{};
return i; // возвращает int
}
Вопрос не о преимуществах, а о том, какой тип возвращаемого значения из функции вы хотите получить.:)
Первая ваша функция имеет неопределенное поведение, так как возвращается ссылка на локальный объект функции, который прекратит свое существование после выхода из функции. Поэтому ссылка будет не действительной.
Рассмотрите также следующий пример.
Данная программа не будет компилироваться.
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
Можете заглянуть в эту тему, где в конце нее я писал про различные способы инициализации.:)
Нет никаких плюсов. Это любо причудливый стиль кодирования отдельных компаний, либо же результат работы автогенератора, в котором, возможно, произведение подобного результата оправдано какими-то причинами.
Как Вы сами заметили в вопросе, разница появилась лишь в C++14 и, на мой взгляд, является чисто академической.
Из скобок можно получить интересный хак (говорят, не по стандарту, но везде работает):
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
- это не функция.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Есть две машины на Linux, подключённые к одному Wi-Fi роутеруНужно реализовать на них эхо-сервер на C\C++
Начал изучать c++Может кто подробно объяснить чем отличаются эти варианты инициализации? Когда что вызывается и т
Просто есть строка string, в ней слова, разделенные пробеламиКак пройтись по этой строке, поочередно занося в буфер эти слова
Есть символ С и строки S1, S2Перед каждым входжением символа С в строку S1 нужно вставить строку S2