C++ åèæå
- C++11
- C++14
- C++17
- C++20
- C++ ç¼è¯å¨æ¯ææ åµè¡¨
- ç¬ç«ä¸å®¿ä¸»å®ç°
- C++ è¯è¨
- å鿍¡æ¿(C++14 èµ·)
- æ´æ°åé¢é
- èååå§å
- æ¯è¾è¿ç®ç¬¦
- é»è®¤æ¯è¾(C++20 èµ·)
- 转ä¹åºå
- for 循ç¯
- while 循ç¯
- ç¨æ·å®ä¹è½¬æ¢
- SFINAE
- 䏻彿°
- ASCII ç 表
- æ è¯ç¬¦
- ç±»å
- å 忍¡å
- 对象
- åºæ¬æ¦å¿µ
- 表达å¼
- 声æ
- åå§å
- 彿°
- è¯å¥
- ç±»
- è¿ç®ç¬¦éè½½
- 模æ¿
- å¼å¸¸
- äºå¡æ§å å
- å ä½ç¬¦ç±»å说æç¬¦ (C++11 èµ·)
- decltype 说æç¬¦
- 彿°å£°æ
- final 说æç¬¦ (C++11 èµ·)
- override 说æç¬¦(C++11 èµ·)
- å¼ç¨å£°æ
- ç§»å¨æé 彿°
- ç§»å¨èµå¼è¿ç®ç¬¦
- æä¸¾å£°æ
- constexpr 说æç¬¦(C++11 èµ·)
- å表åå§å (C++11 èµ·)
- æé 彿°ä¸æååå§åå¨å表
- using 声æ
- nullptrï¼æéåé¢é
- åºç¡ç±»å
- ç±»åå«åï¼å«å模ç (C++11 èµ·)
- å½¢åå
- èåä½å£°æ
- å符串åé¢é
- ç¨æ·å®ä¹åé¢é (C++11 èµ·)
- 屿§è¯´æç¬¦åºå(C++11 èµ·)
- Lambda è¡¨è¾¾å¼ (C++11 èµ·)
- noexcept 说æç¬¦ (C++11 èµ·)
- noexcept è¿ç®ç¬¦ (C++11 èµ·)
- alignof è¿ç®ç¬¦(C++11 èµ·)
- alignas 说æç¬¦ (C++11 èµ·)
- åå¨ç±»è¯´æç¬¦
- åºäºèå´ç for å¾ªç¯ (C++11 èµ·)
- static_assert 声æ
- éå¼è½¬æ¢
- 代ç¨è¿ç®ç¬¦è¡¨ç¤º
- èªå¢/èªåè¿ç®ç¬¦
- æå 表达å¼(C++17 èµ·)
- 类模æ¿å®åæ¨å¯¼(C++17 èµ·)
- 模æ¿å½¢å䏿¨¡æ¿å®å
- if è¯å¥
- inline 说æç¬¦
- ç»æåç»å®å£°æ (C++17 èµ·)
- switch è¯å¥
- å符åé¢é
- å½å空é´
- æ±å¼é¡ºåº
- å¤å¶æ¶é¤
- consteval 说æç¬¦ (C++20 èµ·)
- constinit 说æç¬¦ (C++20 èµ·)
- åç¨ (C++20)
- 模å (C++20 èµ·)
- 约æä¸æ¦å¿µ (C++20 èµ·)
- new 表达å¼
- do-while 循ç¯
- continue è¯å¥
- break è¯å¥
- goto è¯å¥
- return è¯å¥
- 卿å¼å¸¸è¯´æ
- throw 表达å¼
- try å
- å½å空é´å«å
- 类声æ
- cvï¼const ä¸ volatileï¼ç±»åéå®ç¬¦
- é»è®¤åå§å
- å¼åå§å(C++03 èµ·)
- é¶åå§å
- å¤å¶åå§å
- ç´æ¥åå§å
- 常éåå§å
- å¼ç¨åå§å
- å¼ç±»å«
- C++ è¿ç®ç¬¦ä¼å 级
- å¸å°åé¢é
- æµ®ç¹åé¢é
- typedef 说æç¬¦
- æ¾å¼ç±»å转æ¢
- static_cast 转æ¢
- dynamic_cast 转æ¢
- const_cast 转æ¢
- reinterpret_cast 转æ¢
- delete 表达å¼
- æé 彿°ä¸æååå§åå¨å表
- this æé
- 访é®è¯´æç¬¦
- åå 声æ
- virtual 彿°è¯´æç¬¦
- explicit 说æç¬¦
- éææå
- é»è®¤æé 彿°
- å¤å¶æé 彿°
- å¤å¶èµå¼è¿ç®ç¬¦
- ææå½æ°
- 类模æ¿
- 彿°æ¨¡æ¿
- æ¾å¼ï¼å ¨ï¼æ¨¡æ¿ç¹å
- æ±ç¼å£°æ
- C++ çåå²
- ä½ç¨å
- çåæ
- å®ä¹ä¸åä¸å®ä¹è§åï¼ODRï¼
- å忥æ¾
- æéå®çå忥æ¾
- æ éå®çå忥æ¾
- å¦åè§å
- æªå®ä¹è¡ä¸º
- ç¿»è¯é¶æ®µ
- 常é表达å¼
- èµå¼è¿ç®ç¬¦
- ç®æ¯è¿ç®ç¬¦
- é»è¾è¿ç®ç¬¦
- æå访é®è¿ç®ç¬¦
- å ¶ä»è¿ç®ç¬¦
- sizeof è¿ç®ç¬¦
- typeid è¿ç®ç¬¦
- æé声æ
- æ°ç»å£°æ
- è¯è¨é¾æ¥
- 详述类å说æç¬¦
- é»è®¤å®å
- åé¿å®å
- å®åä¾èµæ¥æ¾
- éè½½å³è®®
- éè½½å½æ°çå°å
- æ³¨å ¥ç±»å
- ééææ°æ®æå
- ééææå彿°
- åµå¥ç±»
- æ´¾çç±»
- 空åºç±»ä¼å
- æ½è±¡ç±»
- ä½å
- è½¬æ¢æé 彿°
- æå模æ¿
- 模æ¿å®åæ¨å¯¼
- é¨å模æ¿ç¹å
- sizeof... è¿ç®ç¬¦
- å¾ å³å
- 彿° try å
- æ©å å½åç©ºé´ std
- åæ¯ç¼©å
- RAII
- ä¸/äº/é¶ä¹æ³å
- PImpl
- é¶å¼éåå
- ç±»å
- éå¼è½¬æ¢
- 注é
- C++ å ³é®è¯
- é¢å¤çå¨
- C++ æ ååºå¤´æä»¶
- å ·åè¦æ±
- åè½ç¹æ§æµè¯ (C++20)
- å·¥å ·åº
- ç±»åæ¯æï¼åºæ¬ç±»åãRTTIãç±»åç¹æ§ï¼
- æ¦å¿µåº (C++20)
- é误å¤ç
- 卿å å管ç
- æ¥æåæ¶é´å·¥å ·
- å符串åº
- 容å¨åº
- è¿ä»£å¨åº
- èå´åº (C++20)
- ç®æ³åº
- æ°å¼åº
- è¾å ¥/è¾åºåº
- æä»¶ç³»ç»åº
- æ¬å°ååº
- æ£å表达å¼åº
- ååæä½åº
- çº¿ç¨æ¯æåº
- å®éªæ§ C++ ç¹æ§
- æç¨çèµæº
- ç´¢å¼
- std 符å·ç´¢å¼
- åç¨æ¯æ (C++20)
- C++ å ³é®è¯
ä½ç½®ï¼é¦é¡µ > C++ åèæå >C++ è¯è¨ > 模æ¿å®åæ¨å¯¼
模æ¿å®åæ¨å¯¼
为å®ä¾åä¸ä¸ªå½æ°æ¨¡æ¿ï¼å¿ é¡»ç¥ææ¯ä¸ªæ¨¡æ¿å®åï¼ä½ä¸å¿ æ¯ä¸ªæ¨¡æ¿å®åé½è¢«æå®ãåªè¦å¯è½ï¼ç¼è¯å¨å°±ä¼ä»å½æ°å®åæ¨å¯¼ç¼ºå¤±ç模æ¿å®åãè¿å¨å°è¯è°ç¨å½æ°ãå彿°æ¨¡æ¿å°åæ¶ï¼åæäºå ¶ä»è¯å¢ä¸åçï¼
template<typename To, typename From> To convert(From f);  void g(double d) { int i = convert<int>(d); // è°ç¨ convert<int, double>(double) char c = convert<char>(d); // è°ç¨ convert<char, double>(double) int(*ptr)(float) = convert; // å®ä¾å convert<int, float>(float) }
æ¤æºå¶ä½¿å¾ä½¿ç¨æ¨¡æ¿è¿ç®ç¬¦å¯è¡ï¼å 为é¤äºå°å ¶éåä¸ºå½æ°è°ç¨è¡¨è¾¾å¼ä¹å¤ï¼ä¸åå¨ä¸ºè¿ç®ç¬¦æå®æ¨¡æ¿å®åçè¯æ³ï¼
模æ¿å®åæ¨å¯¼å¨å½æ°æ¨¡æ¿å忥æ¾ï¼å¯è½æ¶åå®åä¾èµæ¥æ¾ï¼ä¹åï¼å¨æ¨¡æ¿å®åæ¿æ¢ï¼å¯è½æ¶å SFINAEï¼åéè½½å³è®®ä¹åè¿è¡ã
|
å½å°ç±»æ¨¡æ¿åç¨ä½æ£å¨æé ç对象çç±»åæ¶ï¼ä¹ä¼è¿è¡æ¨¡æ¿å®åæ¨å¯¼ï¼ std::pair p(2, 4.5); std::tuple t(4, 3, 2.5); std::copy_n(vi1, 3, std::back_insert_iterator(vi2)); std::for_each(vi.begin(), vi.end(), Foo([&](int i) {...})); auto lck = std::lock_guard(foo.mtx); std::lock_guard lck2(foo.mtx, ul); 类模æ¿ç模æ¿å®åæ¨å¯¼åçäºå£°æåæ¾å¼è½¬å表达å¼ä¸ï¼ç»èè§ç±»æ¨¡æ¿å®åæ¨å¯¼ã |
(C++17 èµ·) |
ä»å½æ°è°ç¨æ¨å¯¼
模æ¿å®åæ¨å¯¼è¯å¾ç¡®å®æ¨¡æ¿å®åï¼ç±»å模æ¿å½¢å Ti çç±»åï¼æ¨¡æ¿æ¨¡æ¿å½¢å TTi çæ¨¡æ¿ï¼åéç±»åæ¨¡æ¿å½¢å Ii çå¼ï¼ï¼å¯å°å®æ¿æ¢å°æ¯ä¸ªå½¢å P ä¸ï¼ä»¥äº§çæ¨å¯¼çç±»å Aï¼å¨ç»è¿ä»¥ä¸ååºçè°æ´ä¹åï¼å®ä¸å®å A ç±»åç¸åã
è¥æå¤ä¸ªå½¢å为ï¼åå嫿¨å¯¼æ¯ä¸å¯¹ P/Aï¼ç¶åå并模æ¿å®åãè¥æ¨å¯¼å¤±è´¥ï¼æä»»ä½ä¸å¯¹ P/A ææ§ä¹ï¼æè¥ä¸å对产åºä¸åçæ¨å¯¼åçæ¨¡æ¿å®åï¼æè¥ä»»ä½æ¨¡æ¿å®åä¿çæ¢æªæ¨å¯¼äº¦æªè¢«æ¾å¼æå®ï¼åç¼è¯å¤±è´¥ã
|
è¥ä» template<class T> void f(std::initializer_list<T>); f({1, 2, 3}); // P = std::initializer_list<T>, A = {1, 2, 3} // P'1 = Tï¼A'1 = 1ï¼æ¨åº T = int // P'2 = Tï¼A'2 = 2ï¼æ¨åº T = int // P'3 = Tï¼A'3 = 3ï¼æ¨åº T = int // OKï¼æ¨åº T = int f({1, "abc"}); // P = std::initializer_list<T>ï¼A = {1, "abc"} // P'1 = Tï¼A'1 = 1ï¼æ¨åº T = int // P'2 = Tï¼A'2 = "abc"ï¼æ¨åº T = const char* // éè¯¯ï¼æ¨å¯¼å¤±è´¥ï¼T ææ§ä¹ è¥ä» template<class T, int N> void h(T const(&)[N]); h({1, 2, 3}); // æ¨åº T = intï¼æ¨åº N = 3  template<class T> void j(T const(&)[3]); j({42}); // æ¨åº T = intï¼æ°ç»è¾¹ç䏿¯å½¢åï¼ä¸èè  struct Aggr { int i; int j; }; template<int N> void k(Aggr const(&)[N]); k({1, 2, 3}); // éè¯¯ï¼æ¨å¯¼å¤±è´¥ï¼æ²¡æä» int å° Aggr çè½¬æ¢ k({{1}, {2}, {3}}); // OKï¼æ¨åº N = 3  template<int M, int N> void m(int const(&)[M][N]); m({{1, 2}, {3, 4}}); // æ¨åº M = 2ï¼æ¨åº N = 2  template<class T, int N> void n(T const(&)[N], T); n({{1}, {2}, {3}}, Aggr()); // æ¨åº T = Aggrï¼æ¨åº N = 3 è¥å½¢åå
ä½ä¸ºæåç template<class... Types> void f(Types&...);  void h(int x, float& y) { const int z = x; f(x, y, z); // P = Types&..., A1 = xï¼æ¨åº Types... çç¬¬ä¸æå = int // P = Types&..., A2 = yï¼æ¨åº Types... çç¬¬äºæå = float // P = Types&..., A3 = zï¼æ¨åº Types... çç¬¬ä¸æå = const int // è°ç¨ f<int, float, const int> } |
(C++11 èµ·) |
è¥ P æ¯å½æ°ç±»åã彿°æéç±»åææå彿°æéç±»åï¼ä¸è¥ A æ¯ä¸å«å½æ°æ¨¡æ¿çéè½½å½æ°éï¼åå°è¯ä»¥æ¯ä¸ªéè½½æ¨å¯¼å模æ¿å®åãè¥åªæä¸ä¸ªæåï¼åä½¿ç¨æåçæ¨å¯¼ãè¥æ²¡æææå¤äºä¸ä¸ªæåè
ï¼å模æ¿å½¢åä¸ºéæ¨å¯¼è¯å¢ï¼è§ä¸æï¼ï¼
template<class T> int f(T(*p)(T)); int g(int); int g(char); f(g); // P = T(*)(T)ï¼A = éè½½é // P = T(*)(T)ï¼A1 = int(int)ï¼æ¨åº T = int // P = T(*)(T)ï¼A2 = int(char)ï¼æ æ³æ¨åº T // åªæä¸ä¸ªéè½½ææï¼æ¨å¯¼æå
æ¨å¯¼å¼å§åï¼å¯¹ P å A è¿è¡ä¸åè°æ´ï¼
P 䏿¯å¼ç¨ç±»åï¼A æ¯æ°ç»ç±»åï¼å以仿°ç»å°æé转æ¢è·å¾çæéç±»åæ¿æ¢ Aï¼A æ¯å½æ°ç±»åï¼å以ä»å½æ°å°æé转æ¢è·å¾çæéç±»åæ¿æ¢ Aï¼A æ¯ cv éå®çç±»åï¼å为æ¨å¯¼è忽ç¥é¡¶å± cv éå®ç¬¦ï¼
template<class T> void f(T); int a[3]; f(a); // P = Tï¼A = int[3]ï¼è°æ´ä¸º int*ï¼æ¨åº T = int* void b(int); f(b); // P = Tï¼A = void(int)ï¼è°æ´ä¸º void(*)(int)ï¼æ¨åº T = void(*)(int) const int c = 13; f(c); // P = Tï¼A = const intï¼è°æ´ä¸º intï¼æ¨åº T = int
P æ¯ cv éå®ç±»åï¼å为æ¨å¯¼å¿½ç¥é¡¶å± cv éå®ç¬¦ãP æ¯å¼ç¨ç±»åï¼åç¨ P æå¼ç¨çç±»åæ¨å¯¼ãP æ¯å°æ cv é宿¨¡æ¿å½¢åçå³å¼å¼ç¨ï¼æ¯è°è½¬åå¼ç¨ï¼ï¼ä¸å¯¹åºå½æ°è°ç¨å®å为左å¼ï¼åå°å° A çå·¦å¼å¼ç¨ç±»åç¨äº A çä½ç½®æ¨å¯¼ï¼æ³¨æï¼è¿æ¯ std::forward çè¡å¨åºç¡ï¼æ³¨æï¼ç±»æ¨¡æ¿å®åæ¨å¯¼ä¸ï¼ç±»æ¨¡æ¿ç模æ¿å½¢åå³ä¸ä¼æ¯è½¬åå¼ç¨ (C++17 èµ·)ãï¼ï¼
template<class T> int f(T&&); // P æ¯å°æ cv éå®ç±»å T çå³å¼å¼ç¨ï¼è½¬åå¼ç¨ï¼ template<class T> int g(const T&&); // P æ¯å° cv éå® T çå³å¼å¼ç¨ï¼éç¹æ®ï¼  int main() { int i; int n1 = f(i); // å®å为左å¼ï¼è°ç¨ f<int&>(int&) ï¼ç¹æ®æ åµï¼ int n2 = f(0); // å®åéå·¦å¼ï¼è°ç¨ f<int>(int&&)  // int n3 = g(i); // éè¯¯ï¼æ¨å¯¼åº g<int>(const int&&)ï¼å®ä¸è½ç»å®å³å¼å¼ç¨å°å·¦å¼ }
å¨è¿è¡è¿äºåæ¢ä¹åï¼æä»¥ä¸æè¿°è¿è¡æ¨å¯¼çå¤çï¼åé
èâä»ç±»åæ¨å¯¼âï¼å¹¶è¯å¾æ¾å°å¯ä½¿å¾æ¨å¯¼ç Aï¼å³å¨ä¸é¢ååºçè°æ´åæ¨å¯¼ç模æ¿å½¢åæ¿æ¢åç Pï¼çåäºåæ¢åç Aï¼å³ä¸é¢ååºçè°æ´åç Aï¼ç模æ¿å®åã
è¥æ¥èª P å A çé常æ¨å¯¼å¤±è´¥ï¼åé¢å¤èèä¸åæ¿ç¨è
ï¼
P æ¯å¼ç¨ç±»åï¼åæ¨å¯¼ç Aï¼å³å¼ç¨æææ¶çç±»åï¼è½æ¯åæ¢ç A æ´ä¸º cv éå®ï¼
template<typename T> void f(const T& t); bool a = false; f(a); // P = const T&ï¼è°æ´ä¸º const Tï¼A = boolï¼ // æ¨åº T = boolï¼æ¨åº A = const bool // æ¨å¯¼ç A æ¯ A æ´ä¸º cv éå®
A å¯ä»¥ä¸ºå¦ä¸æéææåæéç±»åï¼å¹¶å¯éè¿éå®è½¬æ¢æå½æ°æéè½¬æ¢ (C++17 èµ·)转æ¢ä¸ºæ¨å¯¼ç Aï¼
template<typename T> void f(const T*); int* p; f(p); // P = const T*ï¼A = int*ï¼ // æ¨å¯¼ T = intï¼æ¨å¯¼ A = const int* // åºç¨éå®è½¬æ¢ï¼ä» int* å° const int*ï¼
P æ¯ç±»ä¸ P çå½¢å¼ä¸º ç®åæ¨¡æ¿æ è¯ï¼å忢åç A å¯ä¸ºæ¨å¯¼ç A çæ´¾çç±»ã类似å°ï¼è¥ P æ¯æå ç®åæ¨¡æ¿æ è¯ å½¢å¼çç±»çæéï¼å忢åç A å¯ä¸ºæ¨å¯¼ç A ææåçæ´¾çç±»çæéï¼
template<class T> struct B { }; template<class T> struct D : public B<T> { }; template<class T> void f(B<T>&) { }  void f() { D<int> d; f(d); // P = B<T>&ï¼è°æ´ä¸º P = B<T>ï¼ç®åæ¨¡æ¿æ è¯ï¼ï¼A = D<int>ï¼ // æ¨å¯¼ T = intï¼æ¨å¯¼ A = B<int> // A 仿¨å¯¼ç A å¯¼åº }
鿍坼è¯å¢
ä¸åæ
åµä¸ï¼ç¨äºç»æ P çç±»åãæ¨¡æ¿åéç±»åå¼ä¸å䏿¨¡æ¿å®åæ¨å¯¼ï¼ä½åè代ä¹å°ä½¿ç¨å¯å¨å«å¤æ¨å¯¼ææ¾å¼æå®ç模æ¿å®åãè¥æ¨¡æ¿å½¢åä»
ç¨äºéæ¨å¯¼è¯å¢ï¼ä¸æªæ¾å¼æå®ï¼å模æ¿å®åæ¨å¯¼å¤±è´¥ã
// æç模æ¿ï¼å¸¸ç¨äºä»æ¨å¯¼ä¸æé¤ç¹å®å®å // ï¼ä» C++20 èµ·å¯ç¨ä½ std::type_identity ï¼ template<typename T> struct identity { typedef T type; }; template<typename T> void bad(std::vector<T> x, T value = 1); template<typename T> void good(std::vector<T> x, typename identity<T>::type value = 1); std::vector<std::complex<double>> x; bad(x, 1.2); // P1 = std::vector<T>ï¼A1 = std::vector<std::complex<double>> // P1/A1ï¼æ¨åº T = std::complex<double> // P2 = Tï¼A2 = double // P2/A2ï¼æ¨åº T = double // éè¯¯ï¼æ¨å¯¼å¤±è´¥ï¼T ææ§ä¹ good(x, 1.2); // P1 = std::vector<T>ï¼A1 = std::vector<std::complex<double>> // P1/A1ï¼æ¨åº T = std::complex<double> // P2 = identity<T>::typeï¼A2 = double // P2/A2ï¼ç¨ P1/A1 æ¨å¯¼ç Tï¼å 为 T å¨ P2 ä¸ç :: ç左侧 // OKï¼T = std::complex<double>
|
2) decltype 说æç¬¦ç表达å¼ï¼
template<typename T> void f(decltype(*std::declval<T>()) arg); int n; f<int*>(n); // P = decltype(*declval<T>())ï¼A = intï¼T å¤äºéæ¨å¯¼è¯å¢ |
(C++14 èµ·) |
template<std::size_t N> void f(std::array<int, 2 * N> a); std::array<int, 10> a; f(a); // P = std::array<int, 2 * N>ï¼A = std::array<int, 10>ï¼ // 2 * N å¤äºéæ¨å¯¼è¯å¢ï¼æ æ³æ¨å¯¼ N // 注æï¼f(std::array<int, N> a) å¯ä»¥æ¨å¯¼ N
template<typename T, typename F> void f(const std::vector<T>& v, const F& comp = std::less<T>()); std::vector<std::string> v(3); f(v); // P1 = const std::vector<T>&ï¼A1 = std::vector<std::string> å·¦å¼ // P1/A1 æ¨åº T = std::string // P2 = const F&ï¼A2 = std::less<std::string> å³å¼ // P2 å¨ç¨äºå½æ°å½¢å comp çå½¢åç±»åï¼const F&ï¼ç Fï¼æ¨¡æ¿å½¢åï¼ç鿍坼è¯å¢ï¼ // è¯¥å½æ°å½¢åæ¥æè°ç¨ f(v) 䏿£å¨ä½¿ç¨çé»è®¤å®å
Pï¼å
¶å®å A æ¯å½æ°ï¼æä½¿å¾å¤äºä¸ä¸ªå½æ°ä¸ P å¹é
æè
没æå½æ°ä¸ P ç¸å¹é
çéè½½éï¼æå
å«ä¸æå¤ä¸ªå½æ°æ¨¡æ¿çéè½½éï¼
|
6) å½¢å Pï¼å
¶å®å A æ¯è±æ¬å·åå§åå¨å表ï¼ä½ P é std::initializer_list ãå°å®çå¼ç¨ï¼å¯æ cv éå®ï¼ï¼æè
å°æ°ç»çå¼ç¨ï¼
template<class T> void g1(std::vector<T>); template<class T> void g2(std::vector<T>, T x); g1({1, 2, 3}); // P = std::vector<T>ï¼A = {1, 2, 3}ï¼T å¨éæ¨å¯¼è¯å¢ // é误ï¼T 鿾弿宿ä»å¦ä¸ P/A æ¨å¯¼åº g2({1, 2, 3}, 10); // P1 = std::vector<T>ï¼A1 = {1, 2, 3}ï¼T å¨éæ¨å¯¼è¯å¢ // P2 = Tï¼A2 = intï¼æ¨åº T = int |
(C++11 èµ·) |
Pï¼
template<class... Ts, class T> void f1(T n, Ts... args); template<class... Ts, class T> void f2(Ts... args, T n); f1(1, 2, 3, 4); // P1 = Tï¼A1 = 1ï¼æ¨åº T = int // P2 = Ts...ï¼A2 = 2ï¼A3 = 3ï¼A4 = 4ï¼æ¨åº Ts = [int, int, int] f2(1, 2, 3, 4); // P1 = Ts...ï¼Ts å¨éæ¨å¯¼è¯å¢
P ä¸ç模æ¿å½¢åå表ï¼ä¸å®å
å«å¹¶éä½äºæ¨¡æ¿å½¢åå表æå°¾ç«¯çå
å±å¼ï¼
template<int...> struct T { };  template<int... Ts1, int N, int... Ts2> void good(const T<N, Ts1...>& arg1, const T<N, Ts2...>&);  template<int... Ts1, int N, int... Ts2> void bad(const T<Ts1..., N>& arg1, const T<Ts2..., N>&);  T<1, 2> t1; T<1, -1, 0> t2; good(t1, t2); // P1 = const T<N, Ts1...>&ï¼A1 = T<1, 2>ï¼ // æ¨åº N = 1ï¼æ¨åº Ts1 = [2] // P2 = const T<N, Ts2...>&ï¼A2 = T<1, -1, 0>ï¼ // æ¨åº N = 1ï¼æ¨åº Ts2 = [-1, 0] bad(t1, t2); // P1 = const T<Ts1..., N>&ï¼A1 = T<1, 2>ï¼ // <Ts1..., N> å¤äºéæ¨å¯¼è¯å¢ // P2 = const T<Ts2..., N>&ï¼A2 = T<1, -1, 0>ï¼ // <Ts2..., N> å¤äºéæ¨å¯¼è¯å¢
P ä¸ç第ä¸ç»´æ°ç»è¾¹çï¼
template<int i> void f1(int a[10][i]); template<int i> void f2(int a[i][20]); // P = int[i][20]ï¼æ°ç»ç±»å template<int i> void f3(int (&a)[i][20]); // P = int(&)[i][20]ï¼å°æ°ç»çå¼ç¨  void g() { int a[10][20]; f1(a); // OKï¼æ¨åº i = 20 f1<20>(a); // OK f2(a); // é误ï¼i å¤äºéæ¨å¯¼è¯å¢ f2<10>(a); // OK f3(a); // OKï¼æ¨åº i = 10 f3<10>(a); // OK }
任使
åµä¸ï¼è¥ç±»ååçä»»ä½é¨åæ¯éæ¨å¯¼çï¼åæ´ä¸ªç±»åå¤äºéæ¨å¯¼è¯å¢ãç¶èï¼åæç±»åè½å
嫿¨å¯¼å鿍坼çç±»ååãä¾å¦ A<T>::B<T2> ä¸ï¼T å 为è§å #1ï¼åµå¥ç±»å说æç¬¦ï¼èä¸ºéæ¨å¯¼çï¼è T2 å ä¸ºå®æ¯åä¸ç±»ååçä¸é¨åèä¸ºéæ¨å¯¼çï¼ä½å¨ void(*f)(typename A<T>::B, A<T>) ä¸ï¼A<T>::B ä¸ç T ä¸ºéæ¨å¯¼çï¼å 为ç¸åè§åï¼ï¼ä¸è¿ A<T> ä¸ç T 坿¨å¯¼ã
ä»ç±»åæ¨å¯¼
ç»å®ä¾èµä¸æå¤ä¸ªç±»å模æ¿å½¢å Tiãæ¨¡æ¿æ¨¡æ¿å½¢å TTi æéç±»åæ¨¡æ¿å½¢å Ii çæ¨¡æ¿å½¢å P åå
¶å¯¹åºå®å Aï¼è¥ P æ¥æä¸åå½¢å¼ä¹ä¸åè¿è¡æ¨å¯¼ï¼
| æ¬èæªå®æ åå ï¼å°½å¯è½ååºå¸¦å¾®ç¤ºä¾çè¡¨æ ¼ |
-
T; -
cv-list T; -
T*; -
T&; -
T&&; -
T[æ´æ°å¸¸é]; -
类模æ¿å<T>; -
ç±»å(T); -
T(); -
T(T); -
T ç±»å::*; -
ç±»å T::*; -
T T::*; -
T(ç±»å::*)(); -
ç±»å(T::*)(); -
ç±»å(ç±»å::*)(T); -
ç±»å(T::*)(T); -
T (ç±»å::*)(T); -
T (T::*)(); -
T (T::*)(T); -
ç±»å[i]; -
类模æ¿å<I>; -
TT<T>; -
TT<I>; -
TT<>;
å ¶ä¸
-
(T)æ¯å ¶ä¸è³å°æä¸ä¸ªå½¢åç±»å嫿 T ç彿°å½¢ååè¡¨ï¼ -
()æ¯å ¶ä¸æ²¡æå«æ T çå½¢åç彿°å½¢ååè¡¨ï¼ -
<T>æ¯è³å°ä¸ä¸ªå®å嫿 T çæ¨¡æ¿å®ååè¡¨ï¼ -
<I>æ¯å ¶ä¸è³å°ä¸ä¸ªå®å嫿 I çæ¨¡æ¿å®ååè¡¨ï¼ -
<>å ¶ä¸æ²¡æå«æ T æ I çå®åçæ¨¡æ¿å®åå表ã
è¥ P å
·æå
嫿¨¡æ¿å½¢åå表 <T> æ <I> çå½¢å¼ä¹ä¸ï¼åå°è¯¥æ¨¡æ¿å½¢ååè¡¨çæ¯ä¸ªå
ç´ Pi ä¸å
¶ A çå¯¹åºæ¨¡æ¿å®å Ai è¿è¡å¹é
ãè¥æåä¸ä¸ª Pi æ¯å
å±å¼ï¼åå°å
¶æ¨¡å¼ä¸ A çæ¨¡æ¿å®åå表ä¸çæ¯ä¸ªå©ä½å®åè¿è¡æ¯è¾ãå
¶ä»æ
åµä¸ä¸æ¨å¯¼çå°¾éåæ°å
ï¼è¢«æ¨å¯¼ä¸ºç©ºå½¢åå
ã
è¥ P å
·æå
å«å½æ°å½¢åå表 (T) çå½¢å¼ï¼åå°æ¥èªè¯¥åè¡¨çæ¯ä¸ªå½¢å Pi 䏿¥èª A ç彿°å½¢åå表ç对åºå®å A è¿è¡æ¯è¾ãè¥æåä¸ä¸ª Pi æ¯å
å±å¼ï¼åå°å
¶å£°æç¬¦å A çå½¢åç±»åå表ä¸çæ¯ä¸ªå©ä½ç Ai è¿è¡æ¯è¾ã
è¿äºå½¢å¼å¯ä»¥åµå¥å¹¶éå½å¤çï¼X<int>(*)(char[6]) æ¯ä¸ä¸ª ç±»å(*)(T) çä¾åï¼å
¶ä¸ ç±»å æ¯ 类模æ¿å<T> è T 为 ç±»å[i]ã
|
ä¸è½ä»éç±»åæ¨¡æ¿å®åæ¨å¯¼æ¨¡æ¿ç±»åå®åï¼ template<typename T, T i> void f(double a[10][i]); double v[10][20]; f(v); // P = double[10][i] ï¼ A = double[10][20]: // i è½è¢«æ¨å¯¼ä¸ºçäº 20 // ä½ä¸è½ä» i çç±»åæ¨å¯¼ T |
(C++17 å) |
|
å½ä»è¡¨è¾¾å¼æ¨å¯¼å¯¹åºäºæä¸ªä»¥å¾ å³ç±»å声æçéç±»åæ¨¡æ¿å½¢å P çå®åç弿¶ï¼ä»è¯¥å¼çç±»åæ¨å¯¼ P çç±»åä¸ç模æ¿å½¢åã template <long n> struct A { }; template <class T> struct C; template <class T, T n> struct C<A<n>> { using Q = T; }; typedef long R;  typedef C<A<2>>::Q R; // OKï¼ä»ç±»å A<2> ä¸ç模æ¿å®å弿¨å¯¼ T 为 long ç±»å template<class T, T i> void f(int (&a)[i]); int v[10]; f(v); // OKï¼T 为 std::size_t |
(C++17 èµ·) |
è¥å¨å½¢åå表ä¸ä½¿ç¨æä¸ªéç±»åæ¨¡æ¿å½¢åï¼ä¸æ¨å¯¼äºå ¶å¯¹åºç模æ¿å®åï¼åæ¨å¯¼ç模æ¿å®åç±»åï¼å¦åå¨å ¶å¤å´æ¨¡æ¿å½¢ååè¡¨ä¸æå®ï¼è¿è¡¨ç¤ºå¼ç¨è¢«ä¿çï¼å¿ é¡»ä¸è¯¥éç±»åæ¨¡æ¿å½¢åçç±»åä¸¥æ ¼å¹é ï¼ä½ cv éå®ç¬¦è¢«ä¸¢å¼ï¼ä¸ä¸å æ¬ä»æ°ç»è¾¹çæ¨å¯¼ç模æ¿å®åââæ¤æ åµä¸å è®¸ä»»ä½æ´åç±»åï¼å³ä½¿æ¯ bool 亦å¯ï¼è½ç¶å®æ»æ¯å为 true å¼ï¼ï¼
template<int i> class A { }; template<short s> void f(A<s>); // éç±»åæ¨¡æ¿å½¢åçç±»åæ¯ short  void k1() { A<1> a; // éç±»åæ¨¡æ¿å½¢åçç±»åæ¯ int f(a); // P = A<(short)s>, A = A<(int)1> // éè¯¯ï¼æ¨åºçéç±»åæ¨¡æ¿å½¢åæ¥æä¸å¯¹åºæ¨¡æ¿å®åä¸åçç±»å f<1>(a); // OKï¼æ¨¡æ¿å®åä¸ºä¸æ¨å¯¼ï¼è¿è°ç¨ f<(short)1>(A<(short)1>) }  template<int&> struct X; template<int& R> void k2(X<R>&); int n; void g(X<n> &x) { k2(x); // P = X<R>ï¼A = X<n> // struct X ç声æä¸å½¢åç±»åæ¯ int& // å®åç±»åæ¯ int& // OKï¼å CWG 2091ï¼ï¼æ¨å¯¼ R æä»£ n }
ç±»åæ¨¡æ¿å½¢åä¸è½ä»å½æ°é»è®¤å®åçç±»åæ¨å¯¼ï¼
template<typename T> void f(T = 5, T = 7);  void g() { f(1); // OKï¼è°ç¨ f<int>(1, 7) f(); // é误ï¼ä¸è½æ¨å¯¼ T f<int>(); // OKï¼è°ç¨ f<int>(5, 7) }
æ¨¡æ¿æ¨¡æ¿å½¢åçæ¨å¯¼å¯ä»¥ä½¿ç¨å½æ°è°ç¨ä¸æç¨ç模æ¿ç¹åä¸æä½¿ç¨çç±»åï¼
template<template<typename> class X> struct A { }; // A æ¯æ¨¡æ¿ï¼æ¥æå½¢å TT template<template<typename> class TT> void f(A<TT>) { } template<class T> struct B { }; A<B> ab; f(ab); // P = A<TT>ï¼A = A<B>ï¼æ¨åº TT = Bï¼è°ç¨ f(A<B>)
å ¶ä»è¯å¢
é¤äºå½æ°è°ç¨åè¿ç®ç¬¦è¡¨è¾¾å¼ä»¥å¤ï¼ä¸åæ å½¢ä¸ä¹ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ï¼
auto ç±»åæ¨å¯¼
å½ä»åéçåå§å卿¨å¯¼ auto 说æç¬¦çå«ä¹æ¶ï¼æ¨¡æ¿å®åæ¨å¯¼ç¨äºåé声æã
以ä¸åæ¹å¼è·å¾å½¢å Pï¼å¨åéç被声æç±»å Tï¼å
å« autoï¼ä¸ï¼auto çæ¯æ¬¡åºç°é½è¢«æ¿æ¢ä¸ºä¸ä¸ªèæç±»å模æ¿å½¢å Uï¼æè¥å
¶åå§å为å¤å¶å表åå§åï¼åæ¿æ¢ä¸º std::initializer_list<U>ãå®å A æ¯åå§åå¨è¡¨è¾¾å¼ãæä¸ææè¿°çè§åä» P å A æ¨å¯¼ U åï¼å°æ¨å¯¼åºç U æ¿æ¢å° P ä¸ï¼ä»¥è·åå®é
çåéç±»åï¼
const auto& x = 1 + 2; // P = const U&ï¼A = 1 + 2ï¼ // ä¸è°ç¨ f(1 + 2) çè§åç¸åï¼å ¶ä¸ f æ¯ // template<class U> void f(const U& u) // æ¨åº U = intï¼x çç±»åæ¯ const int& auto l = {13}; // P = std::initializer_list<U>ï¼A = {13}ï¼ // æ¨åº U = intï¼l 为 std::initializer_list<int>
å¨ç´æ¥å表åå§åï¼ä½ä¸æ¯å¤å¶å表åå§åï¼ä¸ï¼å½ä»è±æ¬å·åå§åå¨å表æ¨å¯¼ auto çå«ä¹æ¶ï¼è±æ¬å·åå§åå¨åè¡¨å¿ é¡»åªå«ä¸ä¸ªå ç´ ï¼è auto çç±»åå°æ¯è¯¥å ç´ çç±»åï¼
auto x1 = {3}; // x1 æ¯ std::initializer_list<int> auto x2{1, 2}; // é误ï¼éåå ç´ auto x3{3}; // x3 æ¯ int //ï¼N3922 ä¹åï¼x2 å x3 å为 std::initializer_list<int>ï¼
è¿å auto ç彿°å½ä» return è¯å¥æ¨å¯¼å½æ°è¿åç±»åä¸ç auto 说æç¬¦çå«ä¹æ¶ï¼å°æ¨¡æ¿å®åæ¨å¯¼ç¨äºå½æ°ç声æã 对äºè¿å auto ç彿°ï¼ä»¥å¦ä¸æ¹å¼è·å¾å½¢å auto f() { return 42; } // P = autoï¼A = 42ï¼ // æ¨åº U = intï¼f çè¿åç±»åæ¯ int è¥è¿ç§å½æ°æ¥æå¤ä¸ª return è¯å¥ï¼å对æ¯ä¸ª return è¯å¥è¿è¡æ¨å¯¼ãææç»æç±»åå¿ é¡»ç¸åï¼å¹¶æä¸ºå ¶å®é è¿åç±»åã è¥è¿ç§å½æ°æ return è¯å¥ï¼åæ¨å¯¼æ¶ 注æï¼åéå彿°å£°æä¸ç decltype(auto) å ä½ç¬¦çå«ä¹ä¸ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ã |
(C++14 èµ·) |
éè½½å³è®®
ä»å鿍¡æ¿å½æ°çæç¹åæ¶ï¼å¨éè½½å³è®®æé´ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ï¼
å
¶ P å A å常è§å½æ°è°ç¨ç¸åã
std::string s; std::getline(std::cin, s); // "std::getline" æå 4 ä¸ªå½æ°æ¨¡æ¿ï¼ // å ¶ä¸ 2 个æ¯åé彿°ï¼å½¢åæ°æ£ç¡®ï¼ // 第 1 å鿍¡æ¿ï¼ // P1 = std::basic_istream<CharT, Traits>&ï¼A1 = std::cin // P2 = std::basic_string<CharT, Traits, Allocator>&ï¼A2 = s // æ¨å¯¼ç¡®å®ç±»å模æ¿å®å CharTãTraits å Allocator // ç¹å std::getline<char, std::char_traits<char>, std::allocator<char>> // 第 2 å鿍¡æ¿ï¼ // P1 = std::basic_istream<CharT, Traits>&&ï¼A1 = std::cin // P2 = std::basic_string<CharT, Traits, Allocator>&ï¼A2 = s // æ¨å¯¼ç¡®å®ç±»å模æ¿å½¢å CharTãTraits å Allocator // ç¹å std::getline<char, std::char_traits<char>, std::allocator<char>> // éè½½å³è®®å°ä»å·¦å¼ std::cin ç»å®çå¼ç¨æå¨é«ä½ // å¹¶éå两个åéç¹åç第ä¸ä¸ª
è¥æ¨å¯¼å¤±è´¥ï¼æè¥æ¨å¯¼æåï¼ä½å®äº§ççç¹åæ æï¼ä¾å¦å½¢åæ¢é类类å亦éæä¸¾ç±»åçéè½½è¿ç®ç¬¦ï¼ï¼ (C++14 èµ·)åéè½½éä¸å å«è¯¥ç¹åï¼è¿ç±»ä¼¼äº SFINAEã
éè½½éçå°å
åå å«å½æ°æ¨¡æ¿å¨å çéè½½éçå°åæ¶ï¼ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ã
彿°æ¨¡æ¿ç彿°ç±»å为 Pãç®æ ç±»å为 A çç±»åï¼
std::cout << std::endl; // std::endl æå彿°æ¨¡æ¿ // endl çç±»å P = // std::basic_ostream<CharT, Traits>& (std::basic_ostream<CharT, Traits>&) // operator<< çå½¢å A = // std::basic_ostream<char, std::char_traits<char>>& (*)( // std::basic_ostream<char, std::char_traits<char>>& // ) // ï¼å ¶ä» operator<< çéè½½ä¸å¯è¡ï¼ // æ¨å¯¼ç¡®å®ç±»å模æ¿å®å CharT å Traits
æ¤æ
åµä¸çæ¨å¯¼éç¨ä¸æ¡é¢å¤çè§åï¼å½æ¯è¾å½æ°å½¢å Pi å Ai æ¶ï¼è¥ä»»ä½ Pi æ¯å°æ cv é宿¨¡æ¿å½¢åçå³å¼å¼ç¨ï¼â转åå¼ç¨âï¼ä¸å¯¹åºç Ai 为左å¼å¼ç¨ï¼åå° Pi è°æ´ä¸ºæ¨¡æ¿å½¢åç±»åï¼T&& æä¸º Tï¼ã
|
è¥å½æ°æ¨¡æ¿çè¿åç±»åæ¯å ä½ç¬¦ï¼auto æ decltype(auto)ï¼ï¼åè¿åç±»åå¤äºéæ¨å¯¼è¯å¢ï¼å¹¶ç±å®ä¾åå³å®ã |
(C++14 èµ·) |
é¨åæåº
对éè½½ç彿°æ¨¡æ¿è¿è¡é¨åæåºæé´ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ã
| æ¬èæªå®æ åå ï¼å°ç¤ºä¾ |
转æ¢å½æ°æ¨¡æ¿
éæ©ç¨æ·å®ä¹è½¬æ¢å½æ°æ¨¡æ¿å®åæ¶ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ã
A æ¯è¦æ±ä½ä¸ºè½¬æ¢ç»æçç±»åã P æ¯è½¬æ¢å½æ°æ¨¡æ¿çè¿åç±»åï¼é¤äº
P 为被å¼ç¨ç±»åï¼A éå¼ç¨ç±»åï¼å P ä¸ºä»æ°ç»å°æé转æ¢è·å¾çæéç±»åï¼A éå¼ç¨ç±»åï¼å P 为ä»å½æ°å°æé转æ¢è·å¾ç彿°æéç±»åï¼P æ cv éå®ï¼å忽ç¥é¡¶å± cv éå®ç¬¦ãè¥ A æ cv éå®ï¼å忽ç¥é¡¶å± cv éå®ç¬¦ãè¥ A æ¯å¼ç¨ç±»åï¼åæ¨å¯¼ä½¿ç¨è¢«å¼ç¨çç±»åã
è¥ä» P å A è¿è¡çå¸¸è§æ¨å¯¼ï¼å¦ä¸ææè¿°ï¼å¤±è´¥ï¼åèèä¸åæ¿ä»£æ¹å¼ï¼
A æ¯å¼ç¨ç±»åï¼å A 坿¯æ¨å¯¼ç A ææ´å¤ cv éå®ï¼A æ¯æéææåæéç±»åï¼åå
许æ¨å¯¼ç A æ¯ä»»ä½è½ä»¥éå®è½¬æ¢è½¬æ¢å° A çæéï¼
struct A { template<class T> operator T***(); }; A a; const int* const* const* p1 = a; // P = T***ï¼A = const int* const* const* // 对 template<class T> void f(T*** p) ç常è§å½æ°è°ç¨æ¨å¯¼ // ï¼å¦å以 const int* const* const* ç±»åçå®åè¿è¡è°ç¨ï¼å¤±è´¥ // 转æ¢å½æ°çé¢å¤æ¨å¯¼ç¡®å® T = int // ï¼æ¨å¯¼ç A 为 int***ï¼å¯è½¬æ¢ä¸º const int* const* const*ï¼
|
c) è¥
A æ¯å½æ°æéç±»åï¼åå
许æ¨å¯¼ç A çæ¯æå noexcept 彿°çæéï¼å¯éè¿å½æ°æé转æ¢è½¬æ¢ä¸º Aï¼d) è¥
A æ¯æå彿°æéï¼åå
许æ¨å¯¼ç A æ¯æå noexcept æå彿°çæéï¼å¯éè¿å½æ°æé转æ¢è½¬æ¢ä¸º Aã |
(C++17 èµ·) |
å ³äºè½¬æ¢å½æ°æ¨¡æ¿çå ¶ä»è§åï¼è§æå模æ¿ã
æ¾å¼å®ä¾å
模æ¿å®åæ¨å¯¼è¢«ç¨äºæ¾å¼å®ä¾åãæ¾å¼ç¹å å声æç¬¦æ è¯æ°å¥½æä»£æä¸ªå½æ°æ¨¡æ¿ç¹åçåå 声æï¼ä¾å¦ friend ostream& operator<< <> (...)ï¼ä¸ï¼è¥å¹¶éæææ¨¡æ¿å®åå被æ¾å¼æå®ææé»è®¤å¼ï¼åç¨æ¨¡æ¿å®åæ¨å¯¼æ¥ç¡®å®æä»£åªä¸ªæ¨¡æ¿ç¹åã
P æ¯è¢«è®¤ä¸ºæ¯æ½å¨å¹é
ç彿°æ¨¡æ¿çç±»åï¼è A æ¯å£°æä¸ç彿°ç±»åãè¥ï¼é¨åæåºåï¼æ å¹é
æå¤äºä¸ä¸ªå¹é
ï¼å彿°å£°æéè¯æï¼
template<class X> void f(X a); // 第 1 æ¨¡æ¿ f template<class X> void f(X* a); // 第 2 æ¨¡æ¿ f template<> void f<>(int* a) { } // f çæ¾å¼ç¹å // P1 = void(X)ï¼A1 = void(int*)ï¼æ¨å¯¼ X = int*ï¼f<int*>(int*) // P2 = void(X*)ï¼A2 = void(int*)ï¼æ¨å¯¼ X = intï¼f<int>(int*) // åé¨åæåºæäº¤ f<int*>(int*) ä¸ f<int>(int*) // å®éæ© f<int>(int*) 为æ´ç¹æ®ç模æ¿
æ¤æ
åµä¸çæ¨å¯¼éç¨ä¸æ¡é¢å¤çè§åï¼å½æ¯è¾å½æ°å½¢å Pi å Ai æ¶ï¼è¥ä»»ä½ Pi æ¯å°æ cv é宿¨¡æ¿å½¢åçå³å¼å¼ç¨ï¼â转åå¼ç¨âï¼ï¼ä¸å¯¹åºç Ai 为左å¼å¼ç¨ï¼åå° Pi è°æ´ä¸ºæ¨¡æ¿å½¢åç±»åï¼T&& æä¸º Tï¼ã
è§£åé 彿°æ¨¡æ¿
ç¡®å®è§£åé
彿°æ¨¡æ¿ç¹åæ¯å¦ä¸ç»å®ç operator new å¸ç½®å½¢å¼ç¸å¹é
æ¶ä½¿ç¨æ¨¡æ¿å®åæ¨å¯¼ã
P ä¸ºè¢«è®¤ä¸ºæ¯æ½å¨å¹é
ç彿°æ¨¡æ¿çç±»åï¼è A 为åºå½ä¸èèä¸çå¸ç½® operator new ç¸å¹é
çè§£åé
彿°ç彿°ç±»åãè¥ï¼å¨éè½½å³è®®åï¼æ å¹é
æå¤äºä¸ä¸ªå¹é
ï¼åä¸è°ç¨å¸ç½®è§£åé
彿°ï¼å¯è½åçå
åæ³æ¼ï¼ï¼
struct X { X() { throw std::runtime_error(""); } static void* operator new(std::size_t sz, bool b) { return ::operator new(sz); } static void* operator new(std::size_t sz, double f) { return ::operator new(sz); } template<typename T> static void operator delete(void* ptr, T arg) { ::operator delete(ptr); } };  int main() { try { X* p1 = new (true) X; // å½ X() æåºå¼å¸¸æ¶ï¼æ¥æ¾ operator delete // P1 = void(void*, T)ï¼A1 = void(void*, bool)ï¼ // æ¨åº T = bool // P2 = void(void*, T)ï¼A2 = void(void*, double)ï¼ // æ¨åº T = double // éè½½å³è®®æé operator delete<bool> } catch(const std::exception&) { } try { X* p1 = new (13.2) X; // åæ ·çæ¥æ¾ï¼æé operator delete<double> } catch(const std::exception&) { } }
å«å模ç
å«å模çå§ç»ä¸è¿è¡æ¨å¯¼ï¼
template<class T> struct Alloc { }; template<class T> using Vec = vector<T, Alloc<T>>; Vec<int> v;  template<template<class, class> class TT> void g(TT<int, Alloc<int>>); g(v); // OKï¼æ¨å¯¼ TT = vector  template<template<class> class TT> void f(TT<int>); f(v); // é误ï¼ä¸è½æ¨å¯¼ TT 为 "Vec"ï¼å 为 Vec æ¯å«å模ç
éå¼è½¬æ¢
ç±»åæ¨å¯¼ä¸èèï¼é¤äºä»¥ä¸ååºçç±»åè°æ´ä¹å¤çï¼éå¼è½¬æ¢ï¼è¿æ¯å ¶åè¿è¡çéè½½å³è®®çå·¥ä½ã
|
ç¶èï¼è¥å¯¹ææå䏿¨¡æ¿å®åæ¨å¯¼çå½¢åè¿è¡çæ¨å¯¼åæåï¼å¹¶ä¸ææä¸æ¨å¯¼ç模æ¿å®åå被æ¾å¼æå®ææé»è®¤å¼ï¼åå°å©ä½çå彿°å½¢åä¸å¯¹åºç彿°å®åæ¯è¾ã对äºå
·æå¨æ¿æ¢ä»»ä½æ¾å¼æå®ç模æ¿å®åä¹åå¹¶éå¾
å³çç±»åçæ¯ä¸ªå©ä½å½¢å å ·æå¾ å³ç±»åçå½¢åï¼å ¶ä¸æ 模æ¿å½¢åå䏿¨¡æ¿å®åæ¨å¯¼ï¼ä»¥åç±äºæ¿æ¢æ¾å¼æå®ç模æ¿å®åèæä¸ºéå¾ å³çå½¢åï¼å°å¨éè½½å³è®®æé´æ£æ¥ï¼ template<class T> struct Z { typedef typename T::x xx; }; template<class T> typename Z<T>::xx f(void*, T); // #1 template<class T> void f(int, T); // #2 struct A { } a;  int main() { f(1, a); // å¯¹äº #1ï¼æ¨å¯¼ç¡®å® T = struct Aï¼ä½å©ä½å®å 1 // ä¸è½éå¼è½¬æ¢æå ¶å½¢å void*ï¼æ¨å¯¼å¤±è´¥ // ä¸è¦æ±è¿åç±»åçå®ä¾å // å¯¹äº #2ï¼æ¨å¯¼ç¡®å®ç¡®å® T = struct Aï¼èå©ä½å®å 1 // è½éå¼è½¬æ¢æå ¶å½¢å intï¼æ¨å¯¼æå // 彿°è°ç¨ç¼è¯ä¸ºå° #2 çè°ç¨ï¼æ¨å¯¼å¤±è´¥æ¯ SFINAEï¼ } |
(C++14 èµ·) |
ç¼ºé·æ¥å
ä¸åæ´æ¹è¡ä¸ºçç¼ºé·æ¥å追溯å°åºç¨äºä»¥ååºçç C++ æ åã
| DR | åºç¨äº | åºçæ¶çè¡ä¸º | æ£ç¡®è¡ä¸º |
|---|---|---|---|
| CWG 1391 | C++14 | æªæåæ¨å¯¼æä¸æ¶åçå®åéå¼è½¬æ¢çææ | æå®ä¸ºå¦ä¸ææè¿° |
| CWG 1591 | C++11 | ä¸è½ä» è±æ¬å·åå§åå¨å表 æ¨å¯¼æ°ç»è¾¹çåå ç´ ç±»å | å 许æ¨å¯¼ |
| CWG 2052 | C++14 | 以éç±»å®åæ¨å¯¼è¿ç®ç¬¦æ¯ç¡¬éè¯¯ï¼æäºç¼è¯å¨ä¸ï¼ | è¥æå ¶ä»éè½½å为软é误 |
| CWG 2091 | C++98 | æ¨å¯¼å¼ç¨éç±»åå½¢åä¸å¯ç¨ï¼å 为类åä¸è½å¹é å®å | é¿å ç±»åä¸å¹é |
| N3922 | C++11 | auto çç´æ¥å表åå§åæ¨å¯¼åº std::initializer_list
|
对 >1 个å ç´ ä¸ºéè¯æï¼å¯¹å个å ç´ æ¨åºå ç´ ç±»å |