Skip to content

Commit

Permalink
Finished 16.2
Browse files Browse the repository at this point in the history
  • Loading branch information
pezy chen committed May 13, 2018
1 parent db498da commit 9cee9eb
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 155 deletions.
54 changes: 53 additions & 1 deletion ch16/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,4 +377,56 @@ auto sum(T1 a, T2 b) -> decltype(a + b) {
}
```
More safer solution: <[Better `sum`](ex16_41_sum.cpp)>
More safer solution: <[Better `sum`](ex16_41_sum.cpp)>
## Exercise 16.42
> Determine the type of T and of val in each of the following calls:
> ```cpp
> template <typename T> void g(T&& val);
> int i = 0; const int ci = i;
> (a) g(i);
> (b) g(ci);
> (c) g(i * ci);
> ```
- (a) `int&`
- (b) `const int&`
- (c) `int`
## Exercise 16.43
> Using the function defined in the previous exercise, what would the template parameter of `g` be if we called `g(i = ci)`?
`int&`
## Exercise 16.44
> Using the same three calls as in the first exercise, determine the types for `T` if `g`’s function parameter is declared as `T` (not `T&&`). What if `g`’s function parameter is `const T&`?
Whatever `g`'s function parameter is declared as `T` or `const T&`, the `T`'s type in this three case would always `int`.
## Exercise 16.45
> Given the following template, explain what happens if we call `g` on a literal value such as 42. What if we call `g` on a variable of type `int`?
> ```cpp
> template <typename T> void g(T&& val) { vector<T> v; }
> ```
If we call `g` on a literal value such as 42, `T` should be `int`, and we get a tempoary variable `v`, which type is `vector<int>`. If we call `g` on a variable of type `int`, then `val` should be a lvalue, `T` should be `int&`(because `int& &&` ==> `int&`), then we would declared a `v` as `vector<int&>`. But the component type of `vector` must be [assignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable), the references are not assignable, thus, `vector<int&>` is not allowed, the compiler would complain about it.
## Exercise 16.46
> Explain this loop from `StrVec::reallocate` in 13.5 (p.530):
> ```cpp
> for (size_t i = 0; i != size(); ++i)
> alloc.construct(dest++, std::move(*elem++));
> ```
Since C++11, [`std::allocator::construct`](http://en.cppreference.com/w/cpp/memory/allocator/construct)'s second parameter is `Args&&... args`. `*elem++` is a certain lvalue, and would be casted to a rvalue reference by `std::move`, then the `construct` would call the move constructor of `std::string` rather than copy constructor.
## Exercise 16.47
> Write your own version of the flip function and test it by calling functions that have lvalue and rvalue reference parameters.
[flip and test](ex16_47_flip.cpp)
91 changes: 0 additions & 91 deletions ch16/ex16.42.43.44.45.46/main.cpp

This file was deleted.

63 changes: 0 additions & 63 deletions ch16/ex16.47/main.cpp

This file was deleted.

24 changes: 24 additions & 0 deletions ch16/ex16_47_flip.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <iostream>

void f(int v1, int& v2)
{
std::cout << v1 << " " << ++v2 << std::endl;
}

void g(int&& i, int& j)
{
std::cout << i << " " << ++j << std::endl;
}

template <typename F, typename T1, typename T2>
void flip(F f, T1&& t1, T2&& t2)
{
f(std::forward<T2>(t2), std::forward<T1>(t1));
}

int main()
{
int j = 0;
flip(f, j, 42);
flip(g, j, 42);
}

0 comments on commit 9cee9eb

Please sign in to comment.