From 35c524d171e1e05e14f72b8e36ce3127395da876 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Mon, 18 Mar 2019 20:54:30 +0800 Subject: [PATCH 01/12] Change answer Ex16.42 Solution to Excercise 16.42 is uncomplete. Added explanation. --- ch16/README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ch16/README.md b/ch16/README.md index 4e0a2c39..5cfe63c8 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -340,7 +340,7 @@ Yes. Specify the parameter explicitly: > int a = 6; double b = 6.1231; > std::cout << std::max<long double>(a, b) << std::endl; > ``` -> Normal conversions also apply for arguments whose template type parameter is explicitly specified +> Normal conversions also apply for arguments whose template type parameter is explicitly specified. ## Exercise 16.38 @@ -395,9 +395,13 @@ More safer solution: <[Better `sum`](ex16_41_sum.cpp)> > (c) g(i * ci); > ``` -- (a) `int&` -- (b) `const int&` -- (c) `int` +- (a) T: `int&` val: int& && -> int & +- (b) T: `const int&` val: const int& && -> const int & +- (c) T: `int` val: int && + +> When we pass an lvalue `int` to a function parameter that is an rvalue reference to a template type parameter `T&&`, the compiler deduces the template type parameter as the argument’s lvalue reference type `int &`. + +> `X& &`, `X& &&`, and `X&& &` all collapse to type `X&`. ## Exercise 16.43 From 292898a77f2779b18b580018cdb691701b8a0db8 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Mon, 18 Mar 2019 20:55:35 +0800 Subject: [PATCH 02/12] Update README.md --- ch16/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch16/README.md b/ch16/README.md index 5cfe63c8..a93ece03 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -395,9 +395,9 @@ More safer solution: <[Better `sum`](ex16_41_sum.cpp)> > (c) g(i * ci); > ``` -- (a) T: `int&` val: int& && -> int & -- (b) T: `const int&` val: const int& && -> const int & -- (c) T: `int` val: int && +- (a) T: `int&` val: `int& &&` -> `int &` +- (b) T: `const int&` val: `const int& &&` -> `const int &` +- (c) T: `int` val: `int &&` > When we pass an lvalue `int` to a function parameter that is an rvalue reference to a template type parameter `T&&`, the compiler deduces the template type parameter as the argument’s lvalue reference type `int &`. From 33851d2bb1fce7afe12ac443f0009abfa4d16636 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Mon, 18 Mar 2019 20:57:25 +0800 Subject: [PATCH 03/12] Update README.md --- ch16/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch16/README.md b/ch16/README.md index a93ece03..828a2adf 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -395,9 +395,9 @@ More safer solution: <[Better `sum`](ex16_41_sum.cpp)> > (c) g(i * ci); > ``` -- (a) T: `int&` val: `int& &&` -> `int &` +- (a) T: `int&` val: `int& &&` -> `int &` - (b) T: `const int&` val: `const int& &&` -> `const int &` -- (c) T: `int` val: `int &&` +- (c) T: `int` val: `int &&` > When we pass an lvalue `int` to a function parameter that is an rvalue reference to a template type parameter `T&&`, the compiler deduces the template type parameter as the argument’s lvalue reference type `int &`. From 8d235eb656bfb49b35cc928d96ab57ba01500841 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Tue, 19 Mar 2019 22:28:40 +0800 Subject: [PATCH 04/12] Add answer to exercise 16.49 Add answer to exercise 16.49 --- ch16/README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ch16/README.md b/ch16/README.md index 828a2adf..f1148bfa 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -439,3 +439,28 @@ Since C++11, [`std::allocator::construct`](http://en.cppreference.com/w/cpp/memo > 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) + +## Exercise 16.49 + +> Explain what happens in each of the following calls: +```cpp +template <typename T> void f(T); //1 +template <typename T> void f(const T*); //2 +template <typename T> void g(T); //3 +template <typename T> void g(T*); //4 +int i = 42, *p = &i; +const int ci = 0, *p2 = &ci; +g(42); g(p); g(ci); g(p2); +f(42); f(p); f(ci); f(p2); +``` +> Answer: +```cpp +g(42); //type: int(rvalue) call template 3 T: int instantiation: void g(int) +g(p); //type: int * call template 4 T: int instantiation: void g(int *) +g(ci); //type: const int call template 3 T: const int instantiation: void g(const int) +g(p2); //type: const int * call template 4 T: const int instantiation: void g(const int *) +f(42); //type: int(rvalue) call template 1 T: int instantiation: void f(int) +f(p); //type: int * call template 2 T: int instantiation: void f(const int *) +f(ci); //type: const int call template 1 T: const int instantiation: void f(const int) +f(p2); //type: const int * call template 2 T:int instantiation: void f(const int *) +``` From 98611671c0e39c496d27aedbd74e3b14cdf91181 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 08:40:04 +0800 Subject: [PATCH 05/12] Update README.md --- ch16/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch16/README.md b/ch16/README.md index f1148bfa..17f07e91 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -460,7 +460,7 @@ g(p); //type: int * call template 4 T: int instantiation: void g(ci); //type: const int call template 3 T: const int instantiation: void g(const int) g(p2); //type: const int * call template 4 T: const int instantiation: void g(const int *) f(42); //type: int(rvalue) call template 1 T: int instantiation: void f(int) -f(p); //type: int * call template 2 T: int instantiation: void f(const int *) +f(p); //type: int * call template 1 T: int * instantiation: void f(int *) f(ci); //type: const int call template 1 T: const int instantiation: void f(const int) f(p2); //type: const int * call template 2 T:int instantiation: void f(const int *) ``` From b5aa023c76d422d9dd0ff7a495986f150622b358 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 08:48:47 +0800 Subject: [PATCH 06/12] Add Answer for ex_16_49 --- ch16/ex16_49_overload_template.cpp | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 ch16/ex16_49_overload_template.cpp diff --git a/ch16/ex16_49_overload_template.cpp b/ch16/ex16_49_overload_template.cpp new file mode 100644 index 00000000..ed3fb93a --- /dev/null +++ b/ch16/ex16_49_overload_template.cpp @@ -0,0 +1,38 @@ +#include <iostream> +using std::cout; +using std::endl; + +template <typename T> void f(T) +{ + cout << "template 1\n"; +} + +template <typename T> void f(const T *) +{ + cout << "template 2\n"; +} + +template <typename T> void g(T) +{ + cout << "template 3\n"; +} + +template <typename T> void g(T*) +{ + cout << "template 4\n"; +} + + +int main() +{ + int i = 42, *p = &i; + const int ci = 0, *p2 = &ci; + g(42); + g(p); + g(ci); + g(p2); + f(42); + f(p); + f(ci); + f(p2); +} From dfe8dbe97ce9abfd76b11e3d641628a76c951aff Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 09:48:35 +0800 Subject: [PATCH 07/12] Update README.md --- ch16/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ch16/README.md b/ch16/README.md index 17f07e91..945beb77 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -461,6 +461,7 @@ g(ci); //type: const int call template 3 T: const int instantiation: void g(p2); //type: const int * call template 4 T: const int instantiation: void g(const int *) f(42); //type: int(rvalue) call template 1 T: int instantiation: void f(int) f(p); //type: int * call template 1 T: int * instantiation: void f(int *) +# f(int *) is an exact match for p(int *) while f(const int *) has an conversion from int * to const int *. f(ci); //type: const int call template 1 T: const int instantiation: void f(const int) f(p2); //type: const int * call template 2 T:int instantiation: void f(const int *) ``` From 38ee80323a5ee60c2fcc58585e772ce906eddcb9 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 09:49:44 +0800 Subject: [PATCH 08/12] Add answer for ex_16_52 Add answer for ex_16_52 --- ch16/ex16_52_variadic_template.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ch16/ex16_52_variadic_template.cpp diff --git a/ch16/ex16_52_variadic_template.cpp b/ch16/ex16_52_variadic_template.cpp new file mode 100644 index 00000000..e53708c4 --- /dev/null +++ b/ch16/ex16_52_variadic_template.cpp @@ -0,0 +1,28 @@ +#include <iostream> +#include <string> + +using std::string; +using std::cout; +using std::endl; + +template <typename T, typename ... Args> +void foo(const T & t, const Args& ... rest) +{ + cout << "sizeof...(Args): " << sizeof...(Args) << endl; + cout << "sizeof...(rest): " << sizeof...(rest) << endl; +} + +int main() +{ + int i = 0; + double d = 3.14; + string s = "how now brown cow"; + cout << "foo(i, s, 42, d) : " << endl; + foo(i, s, 42, d); + cout << "foo(s, 42, \"hi\") : " << endl; + foo(s, 42, "hi"); + cout << "foo(d, s) : " << endl; + foo(d, s); + cout << "foo(\"hi\") : " << endl; + foo("hi"); +} From a4b9250722629d4dcdaa87529b2b8f8c04a1a0d7 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 13:36:16 +0800 Subject: [PATCH 09/12] Add answer to ex_16_51 Add answer to ex_16_51 --- ch16/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ch16/README.md b/ch16/README.md index 945beb77..2a5efbc8 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -465,3 +465,17 @@ f(p); //type: int * call template 1 T: int * instantiation: void f(ci); //type: const int call template 1 T: const int instantiation: void f(const int) f(p2); //type: const int * call template 2 T:int instantiation: void f(const int *) ``` + +## Exercise 16.51 + +> Determine what sizeof...(Args) and sizeof...(rest) return for each call to foo in this section. +```cpp +template <typename T, typename ... Args> +void foo(const T & t, const Args & ... rest); +int i = 0; double d = 3.14; string s = "how"; +foo(i, s, 42, d); # input in Args: string, int(rvalue), double sizeof...(Args): 3 sizeof...(rest): 3 +foo(s, 42, "hi"); # input in Args: int(rvalue), const char[3] sizeof...(Args): 2 sizeof...(rest): 2 +foo(d, s); # input in Args: string sizeof...(Args): 1 sizeof...(rest): 1 +foo("hi"); # input in Args: None sizeof...(Args): 0 sizeof...(rest): 0 +foo(i, s, s, d); # input in Args: string, string, double sizeof...(Args): 3 sizeof...(rest): 3 +``` From 57f55ee7fdbf20bac45baa8dad8fff9a99836f26 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 13:38:13 +0800 Subject: [PATCH 10/12] Rename ex16_49_overload_template.cpp to ex16_50_overload_template.cpp --- ...x16_49_overload_template.cpp => ex16_50_overload_template.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ch16/{ex16_49_overload_template.cpp => ex16_50_overload_template.cpp} (100%) diff --git a/ch16/ex16_49_overload_template.cpp b/ch16/ex16_50_overload_template.cpp similarity index 100% rename from ch16/ex16_49_overload_template.cpp rename to ch16/ex16_50_overload_template.cpp From e375c6189d9fce638b215ad258bd48da64d93ccf Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 13:44:26 +0800 Subject: [PATCH 11/12] Update README.md --- ch16/README.md | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/ch16/README.md b/ch16/README.md index 2a5efbc8..4900c747 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -455,27 +455,36 @@ f(42); f(p); f(ci); f(p2); ``` > Answer: ```cpp -g(42); //type: int(rvalue) call template 3 T: int instantiation: void g(int) -g(p); //type: int * call template 4 T: int instantiation: void g(int *) -g(ci); //type: const int call template 3 T: const int instantiation: void g(const int) -g(p2); //type: const int * call template 4 T: const int instantiation: void g(const int *) -f(42); //type: int(rvalue) call template 1 T: int instantiation: void f(int) -f(p); //type: int * call template 1 T: int * instantiation: void f(int *) -# f(int *) is an exact match for p(int *) while f(const int *) has an conversion from int * to const int *. -f(ci); //type: const int call template 1 T: const int instantiation: void f(const int) -f(p2); //type: const int * call template 2 T:int instantiation: void f(const int *) +g(42); // type: int(rvalue) call template 3 T: int instantiation: void g(int) +g(p); // type: int * call template 4 T: int instantiation: void g(int *) +g(ci); // type: const int call template 3 T: const int instantiation: void g(const int) +g(p2); // type: const int * call template 4 T: const int instantiation: void g(const int *) +f(42); // type: int(rvalue) call template 1 T: int instantiation: void f(int) +f(p); // type: int * call template 1 T: int * instantiation: void f(int *) +// f(int *) is an exact match for p(int *) while f(const int *) has an conversion from int * to const int *. +f(ci); // type: const int call template 1 T: const int instantiation: void f(const int) +f(p2); // type: const int * call template 2 T:int instantiation: void f(const int *) ``` -## Exercise 16.51 +## Exercise 16.50 +> Define the functions from the previous exercise so that they print an identifying message. Run the code from that exercise. If the calls behave differently from what you expected, make sure you understand why. +[overload template](ex16_50_overload_template.cpp) + +## Exercise 16.51 > Determine what sizeof...(Args) and sizeof...(rest) return for each call to foo in this section. ```cpp template <typename T, typename ... Args> void foo(const T & t, const Args & ... rest); int i = 0; double d = 3.14; string s = "how"; -foo(i, s, 42, d); # input in Args: string, int(rvalue), double sizeof...(Args): 3 sizeof...(rest): 3 -foo(s, 42, "hi"); # input in Args: int(rvalue), const char[3] sizeof...(Args): 2 sizeof...(rest): 2 -foo(d, s); # input in Args: string sizeof...(Args): 1 sizeof...(rest): 1 -foo("hi"); # input in Args: None sizeof...(Args): 0 sizeof...(rest): 0 -foo(i, s, s, d); # input in Args: string, string, double sizeof...(Args): 3 sizeof...(rest): 3 +foo(i, s, 42, d); // input in Args: string, int(rvalue), double sizeof...(Args): 3 sizeof...(rest): 3 +foo(s, 42, "hi"); // input in Args: int(rvalue), const char[3] sizeof...(Args): 2 sizeof...(rest): 2 +foo(d, s); // input in Args: string sizeof...(Args): 1 sizeof...(rest): 1 +foo("hi"); // input in Args: None sizeof...(Args): 0 sizeof...(rest): 0 +foo(i, s, s, d); // input in Args: string, string, double sizeof...(Args): 3 sizeof...(rest): 3 ``` + +# Exercise 16.52 +> Write a program to check your answer to the previous question. +[variadic template](ex16_52_variadic_template.cpp) + From 46359bbbc1f8768abdf762ff98f8fa10d66504c8 Mon Sep 17 00:00:00 2001 From: BAKEZQ <zhongquan789@126.com> Date: Wed, 20 Mar 2019 13:45:46 +0800 Subject: [PATCH 12/12] Update README.md --- ch16/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ch16/README.md b/ch16/README.md index 4900c747..d42cd9cf 100644 --- a/ch16/README.md +++ b/ch16/README.md @@ -461,13 +461,14 @@ g(ci); // type: const int call template 3 T: const int instantiation: voi g(p2); // type: const int * call template 4 T: const int instantiation: void g(const int *) f(42); // type: int(rvalue) call template 1 T: int instantiation: void f(int) f(p); // type: int * call template 1 T: int * instantiation: void f(int *) -// f(int *) is an exact match for p(int *) while f(const int *) has an conversion from int * to const int *. +// f(int *) is an exact match for p(int *) while f(const int *) has a conversion from int * to const int *. f(ci); // type: const int call template 1 T: const int instantiation: void f(const int) f(p2); // type: const int * call template 2 T:int instantiation: void f(const int *) ``` ## Exercise 16.50 > Define the functions from the previous exercise so that they print an identifying message. Run the code from that exercise. If the calls behave differently from what you expected, make sure you understand why. + [overload template](ex16_50_overload_template.cpp) ## Exercise 16.51 @@ -486,5 +487,6 @@ foo(i, s, s, d); // input in Args: string, string, double sizeof...(Args # Exercise 16.52 > Write a program to check your answer to the previous question. + [variadic template](ex16_52_variadic_template.cpp)