Effective.Modern.C++ 笔记 Item 1: Understand template type deduction
2015-02-02 10:58
721 查看
这一个条目讲的是以前尚未在 《Effective C++》系列中讲的C++的模板的类型推导。
第一个条目就是模板,其对于现代C++的重要性不言自喻。
书中先写出伪代码,以供下列使用。
ParamType 代表推导出的类型。
调用:
OK, 下面开始正餐:
C++ 模板的类型推导分三种情况
类型推导会执行以下工作
1. 当调用时传入的expr 为引用时, 忽略引用部分。
2. 然后模式匹配 expr 与 ParamType。
例子:
类型推导的结果如下
f(x)的推导结果很自然,而f(cx) 和 f(rx) 则是语言本身为了保持传入参数的不可变性, 也就是const 属性。cx和 rx 都是 具有const属性的类型,自然当做实参引用传递时后也要加 const 喽。: )
ParamTye 为 const T& 时:
x 传入时, ParamType 类型被推导为const int&。
&&是C++ 11 中引入的新符号。
例子如下:
作者在书中将详细情况到ITEM 24.。
其实就是C++11 中的右值引用与左值引用的叠加原则。
具体可以google或者百度,许多文章都解释的很详细。
类型推导过程:1.判断 expr 是否为引用,若是, 忽略引用部分。
2.如果 expr 为const, volatile ,忽略这些。
可以看到 cx 和 rx虽然都具有const, 推导出来还是 为int,和上述的推到过程一致。
但是当传入的是const pointer的时候,为了防止通过复制的pointer改变相对应的值 ,推导出的为 const pointer。
当函数声明为如下时
f(name) 等效于 f(ptrToName)
然后当函数声明为
f函数获取到的是数组而不是指针,也就是可以在f函数中通过sizeof获取数组的长度信息。
下列函数很常见:
当然,作为一个modern C++ coder, 作者提议使用C++11 STL中的array。
函数指针的类型推导和数组差不多。
最后依旧是Tings to remember
• During template type deduction, arguments that are references are treated as
non-references, i.e., their reference-ness is ignored.
• When deducing types for universal reference parameters, lvalue arguments get
special treatment.
• When deducing types for by-value parameters, const and/or volatile argu‐
ments are treated as non-const and non-volatile.
• During template type deduction, arguments that are array or function names
decay to pointers, unless they’re used to initialize references.
第一个条目就是模板,其对于现代C++的重要性不言自喻。
书中先写出伪代码,以供下列使用。
template<typename T> void f(ParamType param);
ParamType 代表推导出的类型。
调用:
f(expr);
OK, 下面开始正餐:
C++ 模板的类型推导分三种情况
Case 1: 当 ParamType 为 T& 或者 const T&
模板函数声明如下时候:template<typename T> void f(T& param); // param is a reference
类型推导会执行以下工作
1. 当调用时传入的expr 为引用时, 忽略引用部分。
2. 然后模式匹配 expr 与 ParamType。
例子:
template<typename T> void f(T& param); // param is a reference
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
类型推导的结果如下
f(x); // T is int, param's type is int& f(cx); // T is const int, // param's type is const int& f(rx); // T is const int, // param's type is const int&
f(x)的推导结果很自然,而f(cx) 和 f(rx) 则是语言本身为了保持传入参数的不可变性, 也就是const 属性。cx和 rx 都是 具有const属性的类型,自然当做实参引用传递时后也要加 const 喽。: )
ParamTye 为 const T& 时:
template<typename T> void f(const T& param); // param is now a ref-to-const int x = 27; const int cx = x; const int& rx = x; f(x); // T is int, param's type is const int& f(cx); // T is int, param's type is const int& f(rx); // T is int, param's type is const int&
x 传入时, ParamType 类型被推导为const int&。
Case 2:ParamType 为 Universal Reference(T&&) 时
当模板函数声明如下时候:template<typename T> void f(T&& param); // param is now a universal reference
&&是C++ 11 中引入的新符号。
例子如下:
template<typename T> void f(T&& param); // param is now a universal refernce int x = 27; const int cx = x; const int& rx = x; f(x); // x is lvalue, so T is int&, // param's type is also int& f(cx); // cx is lvalue, so T is const int&, // param's type is also const int& f(rx); // rx is lvalue, so T is const int&, // param's type is also const int& f(27); // 27 is rvalue, so T is int, // param's type is therefore int&&
作者在书中将详细情况到ITEM 24.。
其实就是C++11 中的右值引用与左值引用的叠加原则。
具体可以google或者百度,许多文章都解释的很详细。
Case 3: ParamType is 不是指针也不是引用(也就是值了)
template<typename T> void f(T param); // param is now passed by value
类型推导过程:1.判断 expr 是否为引用,若是, 忽略引用部分。
2.如果 expr 为const, volatile ,忽略这些。
int x = 27; const int cx = x; const int& rx = x; f(x); // T's and param's types are both int f(cx); // T's and param's types are again both int f(rx); // T's and param's types are still both int
可以看到 cx 和 rx虽然都具有const, 推导出来还是 为int,和上述的推到过程一致。
但是当传入的是const pointer的时候,为了防止通过复制的pointer改变相对应的值 ,推导出的为 const pointer。
template<typename T> void f(T param); // param is still passed by value const char* const ptr = "Fun with pointers"; // ptr is const pointer to const object f(ptr); // pass arg of type const char * const
数组作为参数时的情况
数组在作为参数时大多数情况会decay 成pointer的情况,是C/C++ 程序员应该了解的。const char name[] = "J. P. Briggs"; // name's type is // const char[13] const char * ptrToName = name; // array decays to pointer
当函数声明为如下时
template<typename T> void f(T param);<span style="white-space:pre"> </span>// template with by-value parameter
f(name) 等效于 f(ptrToName)
然后当函数声明为
template<typename T> void f(T& param); // template with by-reference parameter f(name); // pass array to f
f函数获取到的是数组而不是指针,也就是可以在f函数中通过sizeof获取数组的长度信息。
下列函数很常见:
template<typename T, std::size_t N> // see info constexpr std::size_t arraySize(T (&) ) noexcept {
return N;
}
当然,作为一个modern C++ coder, 作者提议使用C++11 STL中的array。
函数指针的类型推导和数组差不多。
最后依旧是Tings to remember
• During template type deduction, arguments that are references are treated as
non-references, i.e., their reference-ness is ignored.
• When deducing types for universal reference parameters, lvalue arguments get
special treatment.
• When deducing types for by-value parameters, const and/or volatile argu‐
ments are treated as non-const and non-volatile.
• During template type deduction, arguments that are array or function names
decay to pointers, unless they’re used to initialize references.
此文章可经本人同意后转载,谢绝百度以及360等利益网站的转载,否则追究到底!
相关文章推荐
- <Effective Mordern C++>笔记:Item 2:Understand auto type deduction.
- 《Effective Modern C++》读书笔记(1) -- 模板类型推导(template type deduction)
- <Effective Mordern C++>笔记:Item 5:Prefer auto to explicit type declarations.
- <Effective Mordern C++>笔记:Item 9:prefer alias declarations to typedefs.
- Item1 Understand template type deduction
- 《Effective Modern C++》读书笔记(2) -- auto类型推导(auto type deduction)
- <Effective Mordern C++>笔记:Item 3:Understand decltype .
- Effective Modern C++ 笔记 第七章 The Concurrency API
- Effective C++ Item 19 Treat class design as type design
- Effective C++_Item5笔记
- modern c++ design 笔记(如何列印一个TYPELIST)
- c++ template笔记(3)非类型模板参数nontype template parameters
- C++之Effective STL学习笔记Item7
- Modern C++ Design学习笔记:Int2Type, Type2Type, TypeSelect
- Effective Modern C++ Item1 模板类型推导详解
- Effective C++_Item7笔记
- Effective Modern C++》Item 3总结
- Effective Modern C++ 笔记 第五章:Rvalue References, Move Semantics, and Perfect Forwarding
- Item 1:将C++视作一系列的语言 Effective C++笔记
- C++之Effective STL学习笔记Item20