Skip to content

Commit d737691

Browse files
author
Michael Blome
committed
local merge conflict
2 parents 45408d6 + c5f0cb7 commit d737691

2 files changed

Lines changed: 182 additions & 33 deletions

File tree

docs/cpp/functions-cpp.md

Lines changed: 134 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int sum(int a, int b)
4646
}
4747
```
4848

49-
The function can invoked, or *called*, from any number of places in the program. The values that are passed to the function are the *arguments*, whose types must be compatible with the parameter types in the function definition.
49+
The function can be `invoked, or *called*, from any number of places in the program. The values that are passed to the function are the *arguments*, whose types must be compatible with the parameter types in the function definition.
5050

5151
```
5252
int main()
@@ -62,23 +62,36 @@ int main()
6262
Functions that are defined at class scope are called member functions. In C++, unlike other languages, a function can also be defined at namespace scope (including the implicit global namespace). Such functions are called *free functions* or *non-member functions*; they are used extensively in the Standard Library.
6363

6464
## Parts of a function declaration
65-
A minimal function *declaration* consists of the return type, function name, and parameter list (which may be empty), along with optional keywords that provide additional instructions to the compiler. A function definition consists of a declaration, plus the *body*, which is all the code between the curly braces. A function declaration followed by a semicolon may appear in multiple places in a program. It must appear prior to any calls to that function in each translation unit. The function definition must appear only once in the program, according to the One Definition Rule (ODR).
65+
A minimal function *declaration* consists of the return type, function name, and parameter list (which may be empty), along with optional keywords that provide additional instructions to the compiler. The following example is a function declaration:
66+
67+
```cpp
68+
int sum(int a, int b);
69+
```
70+
71+
A function definition consists of a declaration, plus the *body*, which is all the code between the curly braces:
72+
73+
```cpp
74+
int sum(int a, int b)
75+
{
76+
return a + b;
77+
}
78+
```
79+
A function declaration followed by a semicolon may appear in multiple places in a program. It must appear prior to any calls to that function in each translation unit. The function definition must appear only once in the program, according to the One Definition Rule (ODR).
6680

6781
The required parts of a function declaration are:
6882

69-
1. The return type, which specifies the type of the value that the function returns, or `void` if no value is returned. In C++11, auto is a valid return type that instructs the compiler to infer the type from the return statement. In C++14, decltype(auto) is also allowed. For more information, see Type Deduction in Return Types below.
83+
1. The return type, which specifies the type of the value that the function returns, or `void` if no value is returned. In C++11, `auto` is a valid return type that instructs the compiler to infer the type from the return statement. In C++14, decltype(auto) is also allowed. For more information, see Type Deduction in Return Types below.
7084

71-
2. The function name, which must begin with a letter or underscore and cannot contain spaces. In general, leading underscores in the Standard Library function names indicate private member functions, or non-member functions that are not intended for use by your code.
85+
2. The function name, which must begin with a letter or underscore and cannot contain spaces. In general, leading underscores in the Standard Library function names indicate private member functions, or non-member functions that are not intended for use by your code.
7286

73-
3. The parameter list, a brace delimited, comma-separated set of zero or more parameters that specify the type and optionally a local name by which the values may be accessed inside the function body.
87+
3. The parameter list, a brace delimited, comma-separated set of zero or more parameters that specify the type and optionally a local name by which the values may be accessed inside the function body.
7488

7589
Optional parts of a function declaration are:
7690

7791
1. `constexpr`, which indicates that the return value of the function is a constant value can be computed at compile time.
7892

7993
```
80-
81-
constexpr float exp(float x, int n)
94+
constexpr float exp(float x, int n)
8295
{
8396
return n == 0 ? 1 :
8497
n % 2 == 0 ? exp(x * x, n / 2) :
@@ -220,6 +233,15 @@ auto Add(const Lhs& lhs, const Rhs& rhs) -> decltype(lhs + rhs)
220233
```
221234
222235
When `auto` is used in conjunction with a trailing return type, it just serves as a placeholder for whatever the decltype expression produces, and does not itself perform type deduction.
236+
237+
238+
## Function local variables
239+
A variable that is declared inside a function body is called a *local variable* or simply a *local*. Non-static locals are only visible inside the function body and, if they are declared on the stack go out of scope when the function exits. When you construct a local variable and return it by value, the compiler can usually perform the return value optimization to avoid unnecessary copy operations. If you return a local variable by reference, the compiler will issue a warning because any attempt by the caller to use that reference will occur after the local has been destroyed.
240+
241+
Local static objects are destroyed during termination specified by `atexit`. If a static object was not constructed because the program's flow of control bypassed its declaration, no attempt is made to destroy that object.
242+
243+
### Static local variables
244+
In C++ a local variable may be declared as static. The variable is only visible inside the function body, but a single copy of the variable exists for all instances of the function.
223245
224246
### <a name="type_deduction"></a> Type deduction in return types (C++14)
225247
In C++14, you can use `auto` to instruct the compiler to infer the return type from the function body without having to provide a trailing return type. Note that `auto` always deduces to a return-by-value. Use `auto&&` to instruct the compiler to deduce a reference.
@@ -234,7 +256,7 @@ auto Add2(const Lhs& lhs, const Rhs& rhs)
234256
}
235257
```
236258
237-
Note that `auto` also does not preserve the const-ness of the type it deduces. For forwarding functions whose return value needs to preserve the const-ness or ref-ness of its arguments, you can use the `decltype(auto)` keyword, which uses the `decltype` type inference rules and preserves all the type information. `decltype(auto)` may be used as an ordinary return value on the left side, or as a trailing return value.
259+
Note that `auto` does not preserve the const-ness of the type it deduces. For forwarding functions whose return value needs to preserve the const-ness or ref-ness of its arguments, you can use the `decltype(auto)` keyword, which uses the `decltype` type inference rules and preserves all the type information. `decltype(auto)` may be used as an ordinary return value on the left side, or as a trailing return value.
238260
239261
The following example (based on code from [N3493](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3493.html)), shows `decltype(auto)` being used to enable perfect forwarding of function arguments in a return type that isn't known until the template is instantiated.
240262
@@ -254,14 +276,110 @@ template<typename F, typename Tuple = tuple<T...>,
254276
}
255277
}
256278
```
257-
258-
## Function local variables
259-
A variable that is declared inside a function body is called a *local variable* or simply a *local*. Non-static locals are only visible inside the function body and, if they are declared on the stack go out of scope when the function exits. When you construct a local variable and return it by value, the compiler can usually perform the return value optimization to avoid unnecessary copy operations. If you return a local variable by reference, the compiler will issue a warning because any attempt by the caller to use that reference will occur after the local has been destroyed.
260-
261-
Local static objects are destroyed during termination specified by `atexit`. If a static object was not constructed because the program's flow of control bypassed its declaration, no attempt is made to destroy that object.
262-
263-
### Static local variables
264-
In C++ a local variable may be declared as static. The variable is only visible inside the function body, but a single copy of the variable exists for all instances of the function.
279+
## Returning multiple values from a function
280+
There are various ways to return more than one value from a function:
281+
1. Encapsulate the values in a named class or struct object. Requires the class or struct definition to be visible to the caller:
282+
283+
```cpp
284+
#include <string>
285+
#include <iostream>
286+
287+
using namespace std;
288+
289+
struct S
290+
{
291+
string name;
292+
int num;
293+
};
294+
295+
S g()
296+
{
297+
string t{ "hello" };
298+
int u{ 42 };
299+
return { t, u };
300+
}
301+
302+
int main()
303+
{
304+
S s = g();
305+
cout << s.name << " " << s.num << endl;
306+
return 0;
307+
}
308+
```
309+
2. Return a std::tuple or std::pair object:
310+
```cpp
311+
#include <tuple>
312+
#include <string>
313+
#include <iostream>
314+
315+
using namespace std;
316+
317+
318+
tuple<int, string, double> f()
319+
{
320+
int i{ 108 };
321+
string s{ "Some text" };
322+
double d{ .01 };
323+
return { i,s,d };
324+
}
325+
326+
int main()
327+
{
328+
auto t = f();
329+
cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl;
330+
331+
// --or--
332+
333+
int myval;
334+
string myname;
335+
double mydecimal;
336+
tie(myval, myname, mydecimal) = f();
337+
cout << myval << " " << myname << " " << mydecimal << endl;
338+
339+
return 0;
340+
}
341+
```
342+
3. Use structured bindings (**Visual Studio 2017 version 15.3 and later**): The advantage of structured bindings is that the variables that store the return values are initialized at the same time they are declared, which in some cases can be significantly more efficient. In this statement --`auto[x, y, z] = f();`-- the brackets introduce and intialize names that are in scope for the entire function block.
343+
344+
```cpp
345+
#include <tuple>
346+
#include <string>
347+
#include <iostream>
348+
349+
using namespace std;
350+
351+
tuple<int, string, double> f()
352+
{
353+
int i{ 108 };
354+
string s{ "Some text" };
355+
double d{ .01 };
356+
return { i,s,d };
357+
}
358+
struct S
359+
{
360+
string name;
361+
int num;
362+
};
363+
364+
S g()
365+
{
366+
string t{ "hello" };
367+
int u{ 42 };
368+
return { t, u };
369+
}
370+
371+
int main()
372+
{
373+
auto[x, y, z] = f(); // init from tuple
374+
cout << x << " " << y << " " << z << endl;
375+
376+
auto[a, b] = g(); // init from POD struct
377+
cout << a << " " << b << endl;
378+
return 0;
379+
}
380+
```
381+
382+
4. Although not "returning values" in the strict sense, you can define any number of parameters to use pass-by reference so that the function can modify or initialize the values of objects that the caller provides. For more information, see [Reference-Type Function Arguments](reference-type-function-arguments.md).
265383

266384
## Function pointers
267385
C++ supports function pointers in the same manner as the C language. However a more type-safe alternative is usually to use a function object.

docs/cpp/lvalues-and-rvalues-visual-cpp.md

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Lvalues and Rvalues (Visual C++) | Microsoft Docs"
2+
title: "Value Categories: Lvalues and Rvalues (Visual C++) | Microsoft Docs"
33
ms.custom: ""
44
ms.date: "11/04/2016"
55
ms.reviewer: ""
@@ -34,22 +34,18 @@ translation.priority.ht:
3434
- "zh-tw"
3535
---
3636
# Lvalues and Rvalues (Visual C++)
37-
Every C++ expression is either an lvalue or an rvalue. An lvalue refers to an object that persists beyond a single expression. You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (`const`) variables, are lvalues. An rvalue is a temporary value that does not persist beyond the expression that uses it. To better understand the difference between lvalues and rvalues, consider the following example:
38-
39-
```
40-
// lvalues_and_rvalues1.cpp
41-
// compile with: /EHsc
42-
#include <iostream>
43-
using namespace std;
44-
int main()
45-
{
46-
int x = 3 + 4;
47-
cout << x << endl;
48-
}
49-
```
50-
51-
In this example, `x` is an lvalue because it persists beyond the expression that defines it. The expression `3 + 4` is an rvalue because it evaluates to a temporary value that does not persist beyond the expression that defines it.
52-
37+
Every C++ expression has a type, and belongs to a *value category*. The value categories are the basis for rules that compilers must follow when creating, copying, and moving temporary objects during expression evaluation. In C++17 the rules were restated to ensure that all compilers behave identically by not creating objects unless they are actually required. The new specified behavior is called "guaranteed copy elision." It helps to make your code more portable and efficient and eliminates the need to provide copy and move constructors for types that never use them.
38+
39+
The C++17 standard defines value categories as follows:
40+
41+
- A *glvalue* is an expression whose evaluation determines the identity of an object, bit-field, or function.
42+
- A *prvalue* is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
43+
- An *xvalue* is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime). [ Example: Certain kinds of expressions involving rvalue references (8.3.2) yield xvalues, such as a call to a function whose return type is an rvalue reference or a cast to an rvalue reference type. ]
44+
- An *lvalue* is a glvalue that is not an xvalue.
45+
- An *rvalue* is a prvalue or an xvalue.
46+
47+
Examples of lvalues include variables, including `const` variables, array elements, bit-fields, unions, and class members. Examples of rvalues include literals, function calls, and temporary objects that are created during expression evalution but accessible only by the compiler.
48+
5349
The following example demonstrates several correct and incorrect usages of lvalues and rvalues:
5450

5551
```
@@ -79,6 +75,41 @@ int main()
7975

8076
> [!NOTE]
8177
> The examples in this topic illustrate correct and incorrect usage when operators are not overloaded. By overloading operators, you can make an expression such as `j * 4` an lvalue.
78+
79+
The following example shows the new behavior for guaranteed copy elision. Note that construction from temporary objects succeeds in both cases despite the absence of a move constructor.
80+
81+
```cpp
82+
#include <iostream>
83+
#include <string>
84+
85+
using namespace std;
86+
87+
struct S {
88+
S(int) { cout << "S(int)" << endl; }
89+
S(S&) = delete;
90+
S(S&&) = delete; // { cout << "move" << endl; }
91+
///...
92+
};
93+
94+
S make_s()
95+
{
96+
// Return value initialized directly at call site.
97+
// In Visual Studio 2015 this does not compile due to deleted move ctor.
98+
return S(42);
99+
}
100+
101+
102+
int main()
103+
{
104+
auto nm = make_s();
105+
S x4 = 5; // Construct from an rvalue.
106+
}
107+
```
108+
The program produces this output:
109+
```output
110+
S(int)
111+
S(int)
112+
```
82113

83114
The terms *lvalue* and *rvalue* are often used when you refer to object references. For more information about references, see [Lvalue Reference Declarator: &](../cpp/lvalue-reference-declarator-amp.md) and [Rvalue Reference Declarator: &&](../cpp/rvalue-reference-declarator-amp-amp.md).
84115

0 commit comments

Comments
 (0)