Skip to content
Snippets Groups Projects
Commit f0551846 authored by Sandipan Mohanty's avatar Sandipan Mohanty
Browse files

Chapter 3 examples

parent 02774a29
Branches
No related tags found
No related merge requests found
#include <iostream>
#include <type_traits>
template < class T >
struct SomeCalc
{
static_assert(std::is_arithmetic<T>::value,"argument T must be an arithmetic type");
constexpr SomeCalc() {}
constexpr auto operator()(const T & t1, const T & t2) const ->decltype(t1+t2)
{
return t1+t2+1; // Let's say there is a bug in the implementation
}
};
auto main() -> int
{
constexpr SomeCalc<int> intadder;
constexpr int res = intadder(1,1);
static_assert(res == 2,"Adder seems to return unexpected result");
SomeCalc<std::string> stradder;
}
#include <iostream>
template <class T>
void copy(T* start, T* end, T* start2)
{
for (; start != end; ++start, ++start2) {
*start2 = *start;
}
}
auto main() -> int
{
double x[10], y[10];
for (auto& num : x)
num = 1;
copy(x, x + 10, y);
for (auto&& num : y)
std::cout << num << "\n";
std::string anames[5] = { "a", "b", "c", "d", "e" };
std::string bnames[5] = { " ", " ", " ", " ", " " };
copy(anames, anames + 5, bnames);
for (auto&& name : bnames)
std::cout << name << "\n";
}
#include <iostream>
#include <string>
#if __has_include(<boost/type_index.hpp>)
#include <boost/type_index.hpp>
constexpr auto use_boost_type_index { true };
#else
#include <typeinfo>
constexpr auto use_boost_type_index { false };
#endif
// plain_type_of(var) returns the typename without reference
// symbols, const qualifiers etc.
//
template <class T>
auto plain_type_of(T&& var) -> std::string
{
if constexpr (use_boost_type_index)
return boost::typeindex::type_id<T>().pretty_name();
else
return typeid(var).name();
}
template <class... Types>
void f(Types&&... args)
{
std::cout << "Printing out typenames without references etc. and values\n";
((std::cout << plain_type_of(args) << ": " << args << "\n"), ...);
}
auto main() -> int
{
const int i { 3 }, j {};
size_t k {}, l { 9 };
const char* cst { "C-style string..." };
std::string cppst { "C++ string..." };
f(i, j, true, k, l, cst, cppst);
}
#include <iostream>
template <typename... Types>
void f(Types... args);
template <typename Type1, typename... Types>
void f(Type1 arg1, Types... rest)
{
std::cout << " The first argument is " << arg1
<< ". Remainder argument list has " << sizeof...(Types) << " elements.\n";
f(rest...);
}
template <>
void f() {}
template <typename... Types>
void g(Types... args)
{
std::cout << "Inside g: going to call function f with the sizes of my arguments\n";
f(sizeof(args)...);
}
int main()
{
std::cout << R"hoho(Calling f(0,true," 123 ");)hoho" << '\n';
f(0, true, "123");
std::cout << R"hoho(Calling g(0,true," 123 ");)hoho" << '\n';
g(0, true, "123");
}
#include <array>
#include <iostream>
#include <list>
#include <numeric>
template <class... Types>
void increment_all(Types&... args) { (++args, ...); }
template <class... Ts>
void h(Ts... args)
{
std::cout << "Printing parameters passed to h \n";
((std::cout << args << "\t"), ...);
std::cout << "\n";
[=, &args...] { return increment_all(args...); }();
std::cout << "\nModified value due to call to increment_all() through lambda \n";
((std::cout << args << "\t"), ...);
std::cout << "\n";
std::cout << "Creating std::array out of parameters...\n";
std::array t { args... };
std::cout << "\nsum = " << std::reduce(t.begin(), t.end()) << "\n";
}
auto main() -> int
{
int i = 0;
std::list l { 0, 2, 4, 8, 16 };
auto it = l.begin();
std::cout << "i = " << i << "; iterator it points to list element of value " << (*it) << "\n";
std::cout << "increment_all(i, it)\n";
increment_all(i, it);
std::cout << "i = " << i << "; iterator it points to list element of value " << (*it) << "\n";
std::cout << "Calling h(1, 2, 3, 4)\n";
h(1, 2, 3, 4);
}
#include <array>
#include <iostream>
#include <list>
#include <numeric>
#include <concepts>
template <class T>
concept Incrementable = requires(T ex) {
{ ++ex };
};
template <Incrementable... Types>
void increment_all(Types&... args) { (++args, ...); }
// For function h() below, we can have as many parameters as
// we want, but those parameters should all be of the same type.
// To express this requirement, we create a variable template
// AllSame_v<T...> which has a value true if all its template
// parameters are true.
//
template <class... Ts>
constexpr bool AllSame_v = true; // general template
template <class First, class Second, class... Rest>
constexpr bool AllSame_v<First, Second, Rest...> // specialization
= std::is_same_v<First, Second> && AllSame_v<Second, Rest...>;
// Now the concept AllSame can be expressed as follows
template <class... Ts> concept AllSame = AllSame_v<Ts...>;
template <class... Ts>
void h(Ts&&... args) requires AllSame<Ts...>
{
std::cout << "Printing parameters passed to h \n";
((std::cout << args << "\t"), ...);
std::cout << "\n";
[=, &args...] { return increment_all(args...); }();
std::cout << "\nModified value due to call to increment_all() through lambda \n";
((std::cout << args << "\t"), ...);
std::cout << "\n";
std::cout << "Creating std::array out of parameters...\n";
std::array t { args... };
std::cout << "\nsum = " << std::reduce(t.begin(), t.end()) << "\n";
}
auto main() -> int
{
int i = 0;
std::list l { 0, 2, 4, 8, 16 };
auto it = l.begin();
std::cout << "i = " << i << "; iterator it points to list element of value " << (*it) << "\n";
std::cout << "increment_all(i, it)\n";
increment_all(i, it);
std::cout << "i = " << i << "; iterator it points to list element of value " << (*it) << "\n";
std::cout << "Calling h(1, 2, 3, 4)\n";
h(1, 2, 3, 4); // No problems!
// h(1, 2, 3, 4.); // Problems!
// h(i, 2, 3, 4); // Problems!
int j = 0;
h(i, j); // No problems!
const int k{7};
std::cout << "Introducing a constant integer k = " << k << "\n";
// h(k, k); // Problems!
// h(i, j, k); // Problems!
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment