void
, also called subroutine. Automatic return type deduction C++14):
std ::map <char , int> GetDictionary () {
return std ::map <char , int >{{'a', 27}, {'b', 3}};
}
Can be expressed as:
auto GetDictionary () {
return std ::map <char , int >{{'a', 27}, {'b', 3}};
}
Sadly you can use only one type for return values, so, no Python like:
#!/usr/bin/env python3
def foo ():
return "Super Variable", 5
name , value = foo ()
print(name + " has value: " + str(value))
With the introduction of structured binding in C++17 you can now:
#include <iostream>
#include <tuple>
using namespace std;
auto Foo () {
return make_tuple ("Super Variable", 5);
}
int main () {
auto [name , value] = Foo ();
cout << name << " has value :" << value << endl;
return 0;
}
#include <string>
to usestd::string
- Check if
str
is empty withstr.empty()
#include <iostream>
#include <string>
int main () {
const std :: string source{"Copy this!"};
std :: string dest = source; // copy string
std :: cout << source << '\n';
std :: cout << dest << '\n';
return 0;
}
Return Value Optimization (RVO):
Type DoSomething () {
Type huge_variable ;
// ... do something
// don't worry , the compiler will optimize it
return huge_variable ;
}
// ...
Type out = DoSomething (); // does not copy
Unless declared static, each local variable invocation has its own copy. Q : What’s the “static initialization order ‘fiasco’ (problem)”?
Default arguments:
#include <iostream >
using namespace std;
string SayHello(const string& to_whom = "world") {
return "Hello " + to_whom + "!";
}
int main () {
// Will call SayHello using the default argument
cout << SayHello () << endl;
// This will override the default argument
cout << SayHello("students") << endl;
return 0;
}
Passing big objects : Pass by reference to avoid copy:
void DoSmth(std :: string huge_string ); // Slow.
void DoSmth(std :: string& huge_string ); // Faster.
use const references : void DoSmth(const std :: string& huge_string );
function calls are expensive - use inline
;
inline int fac(int n) {
if (n < 2) {
return 2;
}
return n * fac(n - 1);
}
int main () {
int fac0 = fac (0);
int fac1 = fac (1);
int fac2 = fac (2);
int fac3 = fac (3);
int fac4 = fac (4);
int fac5 = fac (5);
return fac0 + fac1 + fac2 + fac3 + fac4 + fac5;
}
cosine | arctan |
---|---|
#include <cmath>
// ONE cos function to rule them all
double cos(double x);
float cos(float x);
long double cos(long double x); |
#include <cmath>
double atan(double x);
float atan(float x);
long double atan(long double x); |
#include <cmath>
#include <iostream>
using namespace std;
int main () {
double x_double = 0.0;
float x_float = 0.0;
long double x_long_double = 0.0;
cout << "cos(0)=" << std :: cos(x_double) << '\n';
cout << "cos(0)=" << std :: cos(x_float) << '\n';
cout << "cos(0)=" << std :: cos( x_long_double ) << '\n';
return 0;
}
|
Function overloading : Compiler infers a function from arguments
#include <iostream>
#include <string>
using namespace std;
string TypeOf(int) { return "int"; }
string TypeOf(const string &) { return "string";}
int main () {
cout << TypeOf (1) << endl;
cout << TypeOf("hello") << endl;
return 0;
}
Good Function Example:
#include <vector>
using namespace std;
vector <int> CreateVectorOfZeros (int size) {
vector <int> null_vector (size);
for (int i = 0; i < size; ++i) {
null_vector [i] = 0;
}
return null_vector ;
}
int main () {
vector <int> zeros = CreateVectorOfZeros (10);
return 0;
}
#include <iostream>
namespace fun {
int GetMeaningOfLife (void) { return 42; }
} // namespace fun
namespace boring {
int GetMeaningOfLife (void) { return 0; }
} // namespace boring
int main () {
std :: cout << boring :: GetMeaningOfLife () << std :: endl
<< fun :: GetMeaningOfLife () << std :: endl;
return 0;
}
Namespaces (Only use what you need):
#include <cmath>
#include <iostream>
using std :: cout; // Explicitly use cout. (avoid using namespace std;)
using std :: endl; // Explicitly use endl.
// Self -defined function power shadows std::pow
double pow(double x, int exp) {
double res = 1.0;
for (int i = 0; i < exp; i++) {
res *= x;
}
return res;
}
int main () {
cout << "2.0^2 = " << pow (2.0 , 2) << endl;
return 0;
}
Nameless namespaces : If you find yourself relying on some constants in a file and these constants should not be seen in any other file, put them into a nameless namespace on the top of this file.
namespace {
const int kLocalImportantInt = 13;
const float kLocalImportantFloat = 13.0f;
}