@SylvainCorlay @JohanMabille @QuantStack
Open a terminal (or git bash), cd to your repo and type the following
git checkout master
git pull upstream master
git push origin master
git branch -d my_branch
git checkout -b functional
In the terminal, cd to functional/cpp/single_file
mkdir build
cd build
cmake ..
make
In git-bash, cd to functional/cpp/single_file
mkdir build
cd build
Open "Invite de commandes des outils natifs x64 de VS2015
(just type "natifs" in the search bar of Windows)
cd to C:\Users\your_name\cpp_dauphine\functional\cpp\single_file\build
cmake -G "NMake Makefiles" ..
nmake
double discount_factor(double rate, double maturity)
{
double res = std::exp(-rate * maturity);
return res;
}
void print_discount_factor(double rate, double maturity)
{
double df = discount_factor(rate, maturity);
std::cout << "DF(" << maturity << "," << rate << ") = " << df << std::endl;
// No return statement here
}
The semantic of argument passing is the same as the semantic of initialization
double discount_factor(double rate, double maturity)
{
return std::exp(-rate * maturity);
}
double df = discount_factor(0.04, 2);
is equivalent to
double rate = 0.04;
double maturity = 2.5;
// jump to discount_factor code in memory
return std::exp(-rate * maturity);
Type checking
double discount_factor(double rate, double maturity) { ... }
int main(int argc, char* argv[])
{
const char* rate = "0.04";
double r = 0.04;
double m = 2.5;
discount_factor(rate, m); // Error
discount_factor(r, m); // Ok
return 0;
}
Arguments conversion
double discount_factor(double rate, double maturity) { ... }
int main(int argc, char* argv[])
{
const char* rate = "0.04";
double r = 0.04;
int m = 2;
discount_factor(rate, m); // Error
discount_factor(r, m); // Ok
return 0;
}
Default argument
double discount_factor(double rate, double maturity) { ... }
double d = discount_factor(0.04); // Error
double discount_factor(double rate, double maturity = 1.) { ... }
double d = discount_factor(0.04); // OK - Equivalent to discount_factor(0.04, 1.)
double d = discount_factor(0.04, 2.5) // OK, does not use the default argument
double discount_factor(double rate = 0.01, double maturity) { ... } // Illegal
double my_function(double a1, double a2 = 0., double a3) { ... } // Illegal
double f1() { } // Error: no return value
void f2() { } // OK
double f3() { return 1.2; } // OK
void f4() { return 1.2; } // Error: void function
double f5() { return; } // Error: missing return value
void f6() { return; } // OK
double f7() { return "7"; } // Error: wrong return type
double f8() { return 1; } // OK: conversion from int to double
void inc(int i1, int i2)
{
++i1;
++i2;
}
void client()
{
int i = 4;
int j = 5;
inc(i, j);
std::cout << "i = " << i << std::endl;
std::cout << "j = " << j << std::endl;
}
int i = 4;
int& j = i;
++j;
std::cout << i << std::endl;
int& j; // Error: reference must be initialized
int i = 4;
int j& = i;
int k = 8;
j = k;
++j;
std::cout << i << std::endl;
std::cout << k << std::endl;
void inc(int& i1, int& i2)
{
++i1;
++i2;
}
void client()
{
int i = 4;
int j = 5;
inc(i, j);
std::cout << "i = " << i << std::endl;
std::cout << "j = " << j << std::endl;
}
std::vector<double> discount_factor(std::vector<double> rate, std::vector<double> maturity)
{
std::size_t size = rate.size();
std::vector<double> res(size);
for(size_t i = 0; i < size; ++i)
{
res[i] = std::exp(-rate[i] * maturity[i]);
rate[i] = 0.; // No effect, rate is a copy of the passed argument
}
return res;
}
std::vector<double> discount_factor(std::vector<double>& rate, std::vector<double>& maturity)
{
std::size_t size = rate.size();
std::vector<double> res(size);
for(size_t i = 0; i < size; ++i)
{
res[i] = std::exp(-rate[i] * maturity[i]);
rate[i] = 0.; // Side-effect, the passed argument is changed!
}
return res;
}
std::vector<double> discount_factor(const std::vector<double>& rate, const std::vector<double>& maturity)
{
std::size_t size = rate.size();
std::vector<double> res(size);
for(size_t i = 0; i < size; ++i)
{
res[i] = std::exp(-rate[i] * maturity[i]);
rate[i] = 0.; // Error, cannot modify a const object
}
return res;
}
void discount_factor(const std::vector<double>& rate, const std::vector<double>& maturity,
std::vector<double>& res)
{
std::size_t size = rate.size();
res.resize(size);
for(size_t i = 0; i < size; ++i)
{
res[i] = std::exp(-rate[i] * maturity[i]);
}
}
std::vector<double> discount_factor(const std::vector<double>& rate, const std::vector<double>& maturity);
int main(int argc, char* argv[])
{
double df = discount_factor(0.04, 1.5); // error, cannot convert parameter 1 ...
return 0;
}
int main(int argc, char* argv[])
{
std::vector<double> res = discount_factor(std::vector<double>(1, 0.04), std::vector<double>(1, 1.5));
double df = res[0];
return 0;
}
std::vector<double> discount_factor(const std::vector<double>& rate, const std::vector<double>& maturity);
double discount_factor(double rate, double maturity);
int main(int argc, char* argv[])
{
std::vector<double> r(3, 0.04);
std::vector<double> m(3, 1.5);
std::vector<double> df_vec = discount_factor(r, m);
double df = discount_factor(0.04, 1.5);
return 0;
}
void print(long);
void print(double);
void client()
{
long l = 1L;
double d = 1.5;
int i = 1;
print(l); // Ok, calls print(long)
print(d); // Ok, calls print(double)
print(i); // Error, ambiguous
print(long(i)); // Ok, calls print(long)
print(double(i)); // Ok, calls print(double)
}
int f(int, int);
void f(int, int); // Illegal, overloaded function cannot differ only by return type
double f(double, double); // Ok
int f(int, int);
// f's type : int (int, int)
// f's signature: (int, int)
In the terminal, cd to ../multi_files
Open discount_factor.cpp and follow the instruction
Open main.cpp and follow the instruction
// discount_factor.cpp
double discount_factor(double rate, double maturity)
{
// ...
}
std::vector<double> discount_factor(const std::vector<double> r, const std::vector<double> m)
{
// ...
}
void print_discount_factor(double rate, double maturity)
{
// ...
}
// main.cpp
int main(int argc, char* argv[])
{
double df = discount_factor(0.04, 1.5);
return 0;
}
Try to build the program
mkdir build
cd build
cmake ..
make
Try to build the program
mkdir build
cd build
cmake -G "NMake Makefiles" ..
nmake
double discount_factor(double rate, double maturity);
std::vector<double> discount_factor(const std::vector<double> r, const std::vector<double> m);
void print_discount_factor(double rate, double maturity);
// Syntax of a function declaration:
return_type function_name(arg_type1 arg1, arg_type2 arg2);
// Declaration
double discount_factor(double rate, double maturity = 1.);
// Definition
double discount_factor(double rate, double maturity = 1.) // Illegal
{
return srd::exp(-rate * maturity);
}
// Declaration
double discount_factor(double rate, double maturity = 1.);
// Definition
double discount_factor(double rate, double maturity) // Ok
{
return srd::exp(-rate * maturity);
}
// discount_factor.hpp
double discount_factor(double rate, double maturity);
std::vector<double> discount_factor(const std::vector<double> r, const std::vector<double> m);
void print_discount_factor(double rate, double maturity);
// main.cpp
// Add the following before the main function
#include "discount_factor.hpp"
// discount_factor.cpp
// Add the following before the functions definition
#include "discount_factor.hpp"
Replace the declaration of discount_factor with its definitions
// discount_factor.hpp
double discount_factor(double rate, double maturity)
{
// ...
}
// discount_factor.cpp
// Remove the function double discount_factor(double rate, double maturity)
Try to compile
// discount_factor.hpp
inline double discount_factor(double rate, double maturity)
{
// ...
}
Open "bond_pricer.hpp" and uncomment its content
Include "bond_pricer.hpp" in "main.cpp"
Try to build the program
// discount_factor.hpp
#ifndef DISCOUNT_FACTOR_HPP // Inclusion Guard
#define DISCOUNT_FACTOR_HPP
inline double discount_factor(double rate, double maturity) { ... }
std::vector<double> discount_factor(const std::vector<double> r, const std::vector<double> m);
void print_discount_factor(double rate, double maturity);
#endif // DISCOUNT_FACTOR_HPP
// discount_factor.cpp
int check = 7;
// main.cpp
int check = 4;
// discount_factor.cpp
static int check = 7;
// main.cpp
static int check = 4;
int func()
{
int res = 0;
return ++res;
}
int func_mem()
{
static int res = 0;
return ++res;
}
// bon_pricer.hpp
inilne double discount_factor(double rate, double maturity) { ... }
// main.cpp
#include "discount_factor.hpp"
#include "bond_pricer.hpp"
int main(int argc, char* argv[])
{
double df = discount_factor(0.04, 1.5);
return 0;
}
// discount_factor.hpp
namespace ds1
{
inline double discount_factor(double rate, double maturity) { ... }
}
// bond_pricer.hpp
namespace ds2
{
inline double discount_factor(double rate, double maturity) { ... }
}
// discount_factor.cpp
namespace ds1
{
double discount_factor(double rate, double maturity)
{
// ... same as before
}
}
// main.cpp
int main(int argc, char* argv[])
{
double df = ds1::discount_factor(rate, maturity);
}
namespace my_lib
{
namespace my_module
{
void my_func();
}
}
my_lib::my_module::my_func();
namespace mlm = my_lib::my_module; // namespace alias
mlm::my_func();
using my_lib::my_module::my_func; // using directive
my_func();
using namespace my_lib::my_module; // Evil!
my_func();
using namespace std; // Ultimate Evil!
// discount_factor.cpp
static int check = 7;
// main.cpp
static int check = 4;
// discount_factor.cpp
namespace // Anonymous namespace
{
int check = 7;
}
// check is accessible in discount_factor.cpp only