Począwszy od C ++ 14, często tak jest.
C ++ 14 dodaje przypadek fringe, w którym nawiasy wokół zwracanej wartości mogą zmienić semantykę. Ten fragment kodu przedstawia deklarowane dwie funkcje. Jedyną różnicą są nawiasy wokół zwracanej wartości.
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))
W pierwszym func1
zwraca an, int
aw drugim func1
zwraca an int&
. Różnica w semantyce jest bezpośrednio związana z otaczającymi nawiasami .
Specyfikator auto
w swojej najnowszej postaci został wprowadzony w C ++ 11. W specyfikacji języka C ++ jest to opisane jako:
Określa, że typ deklarowanej zmiennej zostanie automatycznie wydedukowany z jej inicjatora. W przypadku funkcji określa, że typ zwracany jest końcowym typem zwracanym lub zostanie wydedukowany z jego instrukcji powrotu (od C ++ 14)
C ++ 11 również wprowadził decltype
specyfikator, który jest opisany w specyfikacji języka C ++ :
Sprawdza zadeklarowany typ jednostki lub pyta o zwracany typ wyrażenia.
[fantastyczna okazja]
Jeśli argumentem jest nieprzedstawiona nazwa obiektu / funkcji lub wyrażenie dostępu do elementu członkowskiego (element_obiektu lub wskaźnik-> element członkowski), to decltype określa zadeklarowany typ jednostki określony przez to wyrażenie.
Jeśli argument jest jakimkolwiek innym wyrażeniem typu T, to
a) jeśli kategorią wartości wyrażenia jest xvalue, to decltype określa T &&
b) jeśli kategorią wartości wyrażenia jest lwartość, to decltype określa T &
c) w przeciwnym razie decltype określa T
[fantastyczna okazja]
Zauważ, że jeśli nazwa obiektu jest umieszczona w nawiasach, staje się ona wyrażeniem l-wartości, dlatego decltype (arg) i decltype ((arg)) są często różnymi typami.
W C ++ 14 można decltype(auto)
było używać zwracanych typów funkcji. W oryginalnych przykładach pojawia się różnica semantyczna z nawiasami. Wracając do oryginalnych przykładów:
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)
umożliwia wywodzenie końcowego typu zwracanego w funkcji z jednostki / wyrażenia w instrukcji return. W pierwszej wersji return var1;
jest to w praktyce to samo, co zwracanie typu decltype(var1)
( typ int
zwracany przez regułę 1 powyżej), aw drugim przypadku return (var1);
jest faktycznie to samo, co decltype((var1))
( int &
typ zwracany przez regułę 2b).
Nawiasy tworzą zwracany typ int&
zamiast int
, co powoduje zmianę semantyki. Morał z tej historii - „Nie wszystkie nawiasy w zwracanym typie są sobie równe”