Skip to content

Commit be98353

Browse files
committed
draft for function overloading/ function template lcpp
1 parent 2877f10 commit be98353

File tree

1 file changed

+150
-1
lines changed

1 file changed

+150
-1
lines changed

content/posts/cpp-learn.md

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,31 @@ returnType functionName() // This is the function header (tells the compiler abo
296296
// This is the function body (tells the compiler what the function does)
297297
}
298298
```
299-
- A `forward declaration` allows us to tell the compiler about the existence of an identifier before actually defining the identifier.
299+
- A `forward declaration` allows us to tell the compiler about the existence of an identifier before actually defining the identifier. We have to be explicit about the return type.
300+
- e.g.
301+
```cpp
302+
#include <iostream>
303+
#include <type_traits> // for std::common_type_t
304+
305+
// Forward declare
306+
template <typename T, typename U>
307+
auto max(T x, U y) -> std::common_type_t<T, U>; // returns the common type of T and U
308+
309+
int main()
310+
{
311+
std::cout << max(2, 3.5) << '\n';
312+
313+
return 0;
314+
}
315+
316+
// Definition
317+
template <typename T, typename U>
318+
auto max(T x, U y) -> std::common_type_t<T, U>
319+
{
320+
return (x < y) ? y : x;
321+
}
322+
323+
```
300324
301325
### 5.2. name space
302326
- `namespace` is a way to group names (variables, functions, classes) together and avoid name conflicts. It guarantees that all identifiers within the namespace are unique
@@ -1162,10 +1186,135 @@ using FcnType = int(*)(double, char); // FcnType easier to find
11621186
- ... (more)
11631187
- Use type deduction for your variables when the type of the object doesn’t matter.
11641188
- Auto can also be used as a function return type to have the compiler infer the function’s return type from the function’s return statements, though this should be avoided for normal functions.
1189+
- The auto keyword can also be used to declare functions using a trailing return syntax, where the return type is specified after the rest of the function prototype.
1190+
- e.g.
1191+
```cpp
1192+
int add(int x, int y)
1193+
{
1194+
return (x + y);
1195+
}
1196+
1197+
// Using the trailing return syntax, this could be equivalently written as:
1198+
auto add(int x, int y) -> int
1199+
{
1200+
return (x + y);
1201+
}
1202+
1203+
#include <type_traits> // for std::common_type
1204+
1205+
std::common_type_t<int, double> compare(int, double); // harder to read (where is the name of the function in this mess?)
1206+
auto compare(int, double) -> std::common_type_t<int, double>; // easier to read (we don't have to read the return type unless we care)
1207+
```
11651208

11661209
<br>
11671210

1211+
11681212
## 15. Function Overloading and Function Templates
1213+
### 15.1. Function overloading
1214+
- `function overloading` allows us to create multiple functions with the same name, so long as each identically named function has different parameter types/numbers. Return types are not considered for
1215+
- `function delete` using `delete` keywork. delete means “I forbid this”, not “this doesn’t exist”.
1216+
- e.g.
1217+
```cpp
1218+
#include <iostream>
1219+
1220+
// This function will take precedence for arguments of type int
1221+
void printInt(int x)
1222+
{
1223+
std::cout << x << '\n';
1224+
}
1225+
1226+
// This function template will take precedence for arguments of other types
1227+
// Since this function template is deleted, calls to it will halt compilation
1228+
template <typename T>
1229+
void printInt(T x) = delete;
1230+
1231+
int main()
1232+
{
1233+
printInt(97); // okay
1234+
printInt('a'); // compile error
1235+
printInt(true); // compile error
1236+
1237+
return 0;
1238+
}
1239+
```
1240+
- `default-arguments`: is a default value provided for a function parameter. Parameters with default arguments must always be the rightmost parameters, and they are not used to differentiate functions when resolving overloaded functions.
1241+
1242+
### 15.2. Function Templates
1243+
- The template system was designed to simplify the process of creating functions (or classes) that are able to work with different data types (that are compiled and executed).
1244+
- `template types` are sometimes called generic types, and programming using templates is sometimes called generic programming.
1245+
- `placeholder types` use for any parameter types, return types, or types used in the function body that we want to be specified later, by the user of the template.
1246+
- `template parameter declaration` defines any template parameters that will be subsequently used.
1247+
- `function templates` allow us to create a function-like definition that serves as a pattern for creating related functions. In a function template, we use type template parameters as placeholders for any types we want to be specified later. The syntax that tells the compiler we’re defining a template and declares the template types is called a template parameter declaration.
1248+
- Using function templates in multiple files. should be defined in a header file, and then #included wherever needed.
1249+
- `template argument deduction` to have the compiler deduce the actual type that should be used from the argument types in the function call.
1250+
- e.g.
1251+
```cpp
1252+
template <typename T> // this is the template parameter declaration defining T as a type template parameter , `typename` or `class` can be used
1253+
T max(T x, T y) // this is the function template definition for max<T>
1254+
{
1255+
return (x < y) ? y : x;
1256+
}
1257+
1258+
template<>
1259+
int max<int>(int x, int y) // the generated function max<int>(int, int)
1260+
{
1261+
return (x < y) ? y : x;
1262+
}
1263+
1264+
template<>
1265+
double max<double>(double x, double y) // the generated function max<double>(double, double)
1266+
{
1267+
return (x < y) ? y : x;
1268+
}
1269+
1270+
int main()
1271+
{
1272+
std::cout << max<int>(1, 2) << '\n'; // calls max<int>(int, int)
1273+
std::cout << max<>(1, 2) << '\n'; // deduces max<int>(int, int) (non-template functions not considered)
1274+
std::cout << max(1, 2) << '\n'; // calls max(int, int)
1275+
1276+
return 0;
1277+
}
1278+
```
1279+
1280+
- `function templates with multiple template` types example:
1281+
```cpp
1282+
#include <iostream>
1283+
1284+
template <typename T, typename U>
1285+
auto max(T x, U y) // ask compiler can figure out what the relevant return type is
1286+
{
1287+
return (x < y) ? y : x;
1288+
}
1289+
1290+
int main()
1291+
{
1292+
std::cout << max(2, 3.5) << '\n';
1293+
1294+
return 0;
1295+
}
1296+
```
1297+
1298+
- `non-type template parameter` is a template parameter with a fixed type that serves as a placeholder for a constexpr value passed in as a template argument.
1299+
```cpp
1300+
#include <iostream>
1301+
1302+
template <int N> // int non-type template parameter
1303+
void print()
1304+
{
1305+
std::cout << N << '\n';
1306+
}
1307+
1308+
int main()
1309+
{
1310+
print<5>(); // no conversion necessary
1311+
print<'c'>(); // 'c' converted to type int, prints 99
1312+
1313+
return 0;
1314+
}
1315+
```
1316+
1317+
<br>
11691318

11701319
## 16. Compound Types: References and Pointers
11711320
- `Compound data types` (also called composite data type) are data types that can be constructed from fundamental data types (or other compound data types).

0 commit comments

Comments
 (0)