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++ è¯è¨ > 类模æ¿å®åæ¨å¯¼(C++17 èµ·)
类模æ¿å®åæ¨å¯¼(C++17 èµ·)
为äºå®ä¾å类模æ¿ï¼å¿ é¡»ç¥ææ¯ä¸ªæ¨¡æ¿å®åï¼ä½ä¸å¿ æ¯ä¸ªæ¨¡æ¿å®åé½è¢«æå®ãå¨ä¸åè¯å¢ä¸ï¼ç¼è¯å¨ä¼ä»åå§åå¨çç±»åæ¨å¯¼ç¼ºå¤±çæ¨¡æ¿å®åï¼
- 任使å®åéåå鿍¡æ¿åå§åç声æ
std::pair p(2, 4.5); // æ¨å¯¼åº std::pair<int, double> p(2, 4.5); std::tuple t(4, 3, 2.5); // å auto t = std::make_tuple(4, 3, 2.5); std::less l; // å std::less<void> l;
template<class T> struct A { A(T,T); }; auto y = new A{1,2}; // åé çç±»åæ¯ A<int>
- 彿°å¼è½¬å表达å¼
auto lck = std::lock_guard(mtx); // æ¨å¯¼åº std::lock_guard<std::mutex> std::copy_n(vi1, 3, std::back_insert_iterator(vi2)); // æ std::back_inserter(vi2) std::for_each(vi.begin(), vi.end(), Foo([&](int i) {...})); // æ¨å¯¼ Foo<T>ï¼å ¶ä¸ T // æ¯ç¬æç lambda ç±»å
template<class T> struct X { X(T) {} auto operator<=>(const X&) const = default; }; Â template<X x> struct Y { }; Â Y<0> y; // OK ï¼ Y<X<int>(0)> |
(C++20 èµ·) |
类模æ¿çæ¨å¯¼
éå¼çæçæ¨å¯¼æå¼
å½å½æ°å¼è½¬åæåé声æä½¿ç¨ä¸»ç±»æ¨¡æ¿ C çåå为类å说æç¬¦ï¼èä¸å¸¦å®åå表æ¶ï¼ä»¥å¦ä¸æ¹å¼è¿è¡æ¨å¯¼ï¼
- è¥å·²å®ä¹
Cï¼å对ææåç主模æ¿ï¼è¥å ¶å·²å®ä¹ï¼ä¸æå£°æçæ¯ä¸ªæé 彿°ï¼ææé 彿°æ¨¡æ¿ï¼Ciï¼æé ä¸ä¸ªè设ç彿°æ¨¡æ¿Fiï¼ä½¿å¾
-
Fiçæ¨¡æ¿å½¢åæ¯Cçæ¨¡æ¿å½¢ååéï¼è¥Ciæ¯æé 彿°æ¨¡æ¿ï¼Ciçæ¨¡æ¿å½¢åï¼äº¦å å«é»è®¤æ¨¡æ¿å®åï¼ -
Fiç彿°å½¢åæ¯æé 彿°å½¢å -
Fiçè¿åç±»åæ¯Cåéç¯ç»äº <> ä¸ç类模æ¿ç模æ¿å½¢å
-
- è¥æªå®ä¹
Cææªå ¶å£°æä»»ä½æé 彿°ï¼åæ·»å ä¸ä¸ªå¯¼åºèªåæ³çæé 彿°C()çé¢å¤çèè®¾å½æ°æ¨¡æ¿ - 任使
åµä¸ï¼é½æ·»å ä¸ä¸ªå¯¼åºèªåæ³æé 彿°
C(C)çé¢å¤çèè®¾å½æ°æ¨¡æ¿ï¼ç§°ä¹ä¸ºå¤å¶æ¨å¯¼åéã
template<class T> struct A { T t; struct { long a, b; } u; }; A a{1, 2, 3}; // è忍坼åéï¼ template<class T> A<T> F(T, long, long);  template<class... Args> struct B : std::tuple<Args...>, Args... {}; B b{ std::tuple<std::any, std::string>{}, std::any{} }; // è忍坼åéï¼ // template<class... Args> B<Args...> F(std::tuple<Args...>, Args...); // æ¨åº b çç±»å为 B<std::any, std::string> |
(C++20 èµ·) |
ç¶åï¼é对æä¸ªåæ³ç±»ç±»åçè设对象çåå§åï¼è¿è¡æ¨¡æ¿å®åæ¨å¯¼åéè½½å³è®®ï¼å¯¹äºç»æéè½½éèè¨ï¼è¯¥ç±»çåæé 彿°çç¾åä¸å个æå¼ï¼é¤äºè¿åç±»åï¼ç¸å¹é
ï¼å¹¶ä¸ç±è¿è¡ç±»æ¨¡æ¿å®åæ¨å¯¼çè¯å¢æä¾å
¶åå§åå¨ãä½è¥å
¶åå§åå¨å表ç±å个ï¼å¯ä¸º cv éå®çï¼U ç±»åç表达å¼ç»æï¼å
¶ä¸ U æ¯ C çç¹åææ´¾çèª C çç¹åçç±»ï¼åçå»å表åå§åç第ä¸é¶æ®µï¼èèåå§åå¨å表æé 彿°ï¼ã
è¿äºè设æé 彿°æ¯è¯¥åæ³ç±»ç±»åçå
¬å¼æåãè¥æ¨å¯¼æå¼ä»æ¾å¼æé 彿°ç»æï¼åå®ä»¬ä¸º explicitãè¥éè½½å³è®®å¤±è´¥ï¼åç¨åºéè¯æãå¦åï¼éä¸ç F çè¿åç±»åå°±æä¸ºæ¨å¯¼åºç类模æ¿ç¹åã
template<class T> struct UniquePtr { UniquePtr(T* t); }; UniquePtr dp{new auto(2.0)}; // ä¸ä¸ªå£°æçæé 彿°ï¼ // C1ï¼UniquePtr(T*); // éå¼çæçæ¨å¯¼æå¼éï¼ // F1ï¼template<class T> UniquePtr<T> F(T *p); // F2ï¼template<class T> UniquePtr<T> F(UniquePtr<T>); // å¤å¶æ¨å¯¼åé // è¦åå§åçåæ³ç±»ï¼ // struct X { // template<class T> X(T *p); // ä» F1 // template<class T> X(UniquePtr<T>); // ä» F2 // }; // X 对象çç´æ¥åå§åï¼ä»¥ânew double(2.0)â为åå§åå¨ // 鿩坹åºäº T = double çæå¼ F1 çæé 彿° // å¯¹äº T=double ç F1ï¼è¿åç±»åæ¯ UniquePtr<double> // ç»æï¼ // UniquePtr<double> dp{new auto(2.0)}
æè ï¼å¯¹äºæ´å 夿çä¾åï¼æ³¨æï¼âS::Nâæ æ³ç¼è¯ï¼ä½ç¨åè§£æéå®ç¬¦å¹¶é坿¨å¯¼å 容ï¼ï¼
template<class T> struct S { template<class U> struct N { N(T); N(T, U); template<class V> N(V, U); }; };  S<int>::N x{2.0, 1}; // éå¼çæçæ¨å¯¼æå¼æ¯ï¼æ³¨æå·²ç¥ T æ¯ intï¼ // F1ï¼template<class U> S<int>::N<U> F(int); // F2ï¼template<class U> S<int>::N<U> F(int, U); // F3ï¼template<class U, class V> S<int>::N<U> F(V, U); // F4ï¼template<class U> S<int>::N<U> F(S<int>::N<U>); ï¼å¤å¶æ¨å¯¼åéï¼ // 以â{2.0, 1}â为åå§åå¨çç´æ¥å表åå§åçéè½½å³è®® // éæ© U=int ä¸ V=double ç F3ã // è¿åç±»å为 S<int>::N<int> // ç»æï¼ // S<int>::N<int> x{2.0, 1};
ç¨æ·å®ä¹æ¨å¯¼æå¼
ç¨æ·å®ä¹æ¨å¯¼æå¼çè¯æ³æ¯å¸¦å°¾éè¿åç±»åç彿°å£°æçè¯æ³ï¼ä½å®ä»¥ç±»åä¸ºå½æ°åï¼
explicit-说æç¬¦(å¯é) 模æ¿å ( å½¢å声æåå¥ ) -> ç®åæ¨¡æ¿æ è¯ ;
|
|||||||||
ç¨æ·å®ä¹æ¨å¯¼æå¼å¿ é¡»æåä¸ä¸ªç±»æ¨¡æ¿ï¼ä¸å¿ é¡»å¨ç±»æ¨¡æ¿çåä¸è¯ä¹ä½ç¨åï¼å¯ä»¥æ¯å½åç©ºé´æå¤å´ç±»ï¼ä¸å¼å ¥ï¼èä¸å¯¹äºæå类模æ¿ï¼å¿ é¡»æ¥æåæ ·ç访é®ï¼ä½æ¨å¯¼æå¼ä¸æä¸ºè¯¥ä½ç¨åçæåã
æ¨å¯¼æå¼ä¸æ¯å½æ°ä¸æ²¡æå½æ°ä½ãæ¨å¯¼æå¼ä¸ä¼è¢«ååæ¥æ¾ææ¾å°ï¼å¹¶ä¸é¤äºå¨æ¨å¯¼ç±»æ¨¡æ¿å®åæ¶ä¸å ¶ä»æ¨å¯¼æå¼ä¹é´çéè½½å³è®®ä¹å¤ï¼ä¸åä¸éè½½å³è®®ãä¸è½å¨åä¸ç¿»è¯åå ä¸ä¸ºåä¸ç±»æ¨¡æ¿åæ¬¡å£°ææ¨å¯¼æå¼ã
// 模æ¿ç声æ template<class T> struct container { container(T t) {} template<class Iter> container(Iter beg, Iter end); }; // é¢å¤æ¨å¯¼æå¼ template<class Iter> container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>; // ä½¿ç¨ container c(7); // OKï¼ç¨éå¼çæçæå¼æ¨åº T=int std::vector<double> v = { /* ... */}; auto d = container(v.begin(), v.end()); // OKï¼æ¨åº T=double container e{5, 6}; // éè¯¯ï¼æ std::iterator_traits<int>::value_type
为éè½½å³è®®èè设çæé 彿°ï¼å¦ä¸ææè¿°ï¼ï¼è¥å
¶å¯¹åºäºä»æ¾å¼æé 彿°ç»æçéå¼çæçæ¨å¯¼æå¼ï¼æå¯¹åºäºå£°æä¸º explicit çç¨æ·å®ä¹æ¨å¯¼æå¼ï¼å为 explicitãåå¾å¸¸ä¸æ ·ï¼å¨å¤å¶åå§åè¯å¢ä¸å¿½ç¥è¿äºæé 彿°ï¼
template<class T> struct A { explicit A(const T&, ...) noexcept; // #1 A(T&&, ...); // #2 };  int i; A a1 = { i, i }; // é误ï¼ä¸è½ä» #2 çå³å¼å¼ç¨æ¨å¯¼ï¼ä¸ #1 为 explicitï¼å¤å¶åå§åä¸ä¸äºèèã A a2{i, i}; // OKï¼#1 æ¨åº A<int> å¹¶ä¸åå§å A a3{0, i}; // OKï¼#2 æ¨åº A<int> å¹¶ä¸åå§å A a4 = {0, i}; // OKï¼#2 æ¨åº A<int> å¹¶ä¸åå§å  template<class T> A(const T&, const T&) -> A<T&>; // #3 template<class T> explicit A(T&&, T&&) -> A<T>; // #4  A a5 = {0, 1}; // é误ï¼#3 æ¨åº A<int&> ä¸ #1 & #2 çæå½¢åç¸åçæé 彿°ã A a6{0,1}; // OKï¼#4 æ¨åº A<int> 并以 #2 åå§å A a7 = {0, i}; // é误ï¼#3 æ¨åº A<int&> A a8{0,i}; // é误ï¼#3 æ¨åº A<int&>
卿é 彿°ææé 彿°æ¨¡æ¿çå½¢åå表ä¸ä½¿ç¨æå typedef æå«å模æ¿ï¼æ¤è¡ä¸ºèªèº«ä¸ä¼ä½¿éå¼çæçæå¼ç对åºå½¢ååä¸ºéæ¨å¯¼è¯å¢ã
template<class T> struct B { template<class U> using TA = T; template<class U> B(U, TA<U>); //#1 };  // ä» #1 产ççé弿¨å¯¼æå¼çä»·äº // template<class T, class U> B(U, T) -> B<T>; // èé // template<class T, class U> B(U, typename B<T>::template TA<U>) -> B<T>; // è¿æ¯æ æ³æ¨å¯¼ç  B b{(int*)0, (char*)0}; // OKï¼æ¨åº B<char*>
å«å模ççæ¨å¯¼å½æ°é£æ ¼è½¬åæåéå®ä¹ä»¥ä¸å¸¦å®åå表çå«å模æ¿
template<class T> class unique_ptr { /* ... */ }; template<class T> class unique_ptr<T[]> { /* ... */ };  template<class T> unique_ptr(T*) -> unique_ptr<T>; // #1 template<class T> unique_ptr(T*) -> unique_ptr<T[]>; // #2  template<class A> requires(!std::is_array_v<A>) using unique_ptr_nonarray = unique_ptr<A>; template<class A> using unique_ptr_array = unique_ptr<A[]>;  // 对 unique_ptr_nonarray çæçæ¨å¯¼æå¼ï¼ // ä» #1 ï¼ unique_ptr<T> ä» unique_ptr<A> çæ¨å¯¼äº§ç T = A ï¼ï¼ // template<class A> // requires(argument_of_unique_ptr_nonarray_is_deducible_from<unique_ptr<A>>) // auto F(A*) -> unique_ptr<A>; // ä» #2 ï¼ unique_ptr<T[]> ä» unique_ptr<A> çæ¨å¯¼ä¸äº§çç»æï¼ï¼ // template<class T> // requires(argument_of_unique_ptr_nonarray_is_deducible_from<unique_ptr<T[]>>) // auto F(T*) -> unique_ptr<T[]>; // å ¶ä¸ argument_of_unique_ptr_nonarray_is_deducible_from è½å®ä¹ä¸º // template<class> class AA; // template<class A> class AA<unique_ptr_nonarray<A>> {}; // template<class T> // concept argument_of_unique_ptr_nonarray_is_deducible_from = // requires { sizeof(AA<T>); };  // 对 unique_ptr_array çæçæ¨å¯¼æå¼ï¼ // ä» #1 ï¼ unique_ptr<T>ä» unique_ptr<A[]> çæ¨å¯¼çæ T = A[] ï¼ï¼ // template<class A> // requires(argument_of_unique_ptr_array_is_deducible_from<unique_ptr<A[]>>) // auto F(A(*)[]) -> unique_ptr<A[]>; // ä» #2 ï¼ unique_ptr<T[]> ä» unique_ptr<A[]> çæ¨å¯¼çæ T = A ï¼ï¼ // template<class A> // requires(argument_of_unique_ptr_array_is_deducible_from<unique_ptr<A[]>>) // auto F(A*) -> unique_ptr<A[]>; // å ¶ä¸ argument_of_unique_ptr_array_is_deducible_from è½å®ä¹ä¸º // template<class> class BB; // template<class A> class BB<unique_ptr_array<A>> {}; // template<class T> // concept argument_of_unique_ptr_array_is_deducible_from = requires { sizeof(BB<T>); };  // ç¨æ³ï¼ unique_ptr_nonarray p(new int); // æ¨å¯¼åº unique_ptr<int> // ä» #1 çæçæ¨å¯¼æå¼è¿å unique_ptr<int> // ä» #2 çæçæ¨å¯¼æå¼è¿å unique_ptr<int[]> ï¼å®è¢«å¿½ç¥ï¼å 为 // argument_of_unique_ptr_nonarray_is_deducible_from<unique_ptr<int[]>> å¾ä¸å°æ»¡è¶³  unique_ptr_array q(new int[42]); // æ¨å¯¼åº unique_ptr<int[]> // ä» #1 çæçæ¨å¯¼æå¼å¤±è´¥ï¼ä¸è½ä» new int[42] æ¨åº A(*)[] ä¸ç A ï¼ // ä» #2 çæçæ¨å¯¼æå¼è¿å unique_ptr<int[]> |
(C++20 èµ·) |
注解
ä» å½ä¸å卿¨¡æ¿å®ååè¡¨æ¶æè¿è¡ç±»æ¨¡æ¿å®åæ¨å¯¼ãè¥æå®äºæ¨¡æ¿å®åå表ï¼åä¸åçæ¨å¯¼ã
std::tuple t1(1, 2, 3); // OKï¼æ¨å¯¼ std::tuple<int, int, int> t2(1, 2, 3); // OKï¼æä¾ææå®å std::tuple<> t3(1, 2, 3); // é误ï¼tuple<> 䏿 å¹é çæé 彿°ã // ä¸è¿è¡æ¨å¯¼ std::tuple<int> t4(1, 2, 3); // é误
|
èåä½ç类模æ¿å®åæ¨å¯¼å¸¸éè¦ç¨æ·å®ä¹çæ¨å¯¼æå¼ï¼ template<class A, class B> struct Agg {A a; B b; }; // éå¼çæçæå¼ç±é»è®¤ãå¤å¶åç§»å¨æé 彿°ç»æ template<class A, class B> Agg(A a, B b) -> Agg<A, B>; // ^ æ¤æ¨å¯¼æå¼å¨ C++20 ä¸è½éå¼çæ Agg agg{1, 2.0}; // ä»ç¨æ·å®ä¹æå¼æ¨åº Agg<int, double>  template <class... T> array(T&&... t) -> array<std::common_type_t<T...>, sizeof...(T)>; auto a = array{1, 2, 5u}; // ä»ç¨æ·å®ä¹æå¼æ¨åº array<unsigned, 3> |
(C++20 å) |
ç¨æ·å®ä¹æå¼ä¸å¿ æ¯æ¨¡æ¿ï¼
template<class T> struct S { S(T); }; S(char const*) -> S<std::string>; S s{"hello"}; // æ¨åº S<std::string>
å¨ç±»æ¨¡æ¿çä½ç¨åä¸ï¼æ å½¢ååè¡¨çæ¨¡æ¿åæ¯æ³¨å ¥ç±»åï¼å¹¶å¯ç¨ä½ç±»åãè¿ç§æ åµä¸ï¼ä¸åçç±»æ¨¡æ¿æ¨å¯¼ï¼èå¿ é¡»æ¾å¼æä¾å ¶æ¨¡æ¿å½¢åï¼
template<class T> struct X { X(T) { } template<class Iter> X(Iter b, Iter e) { }  template<class Iter> auto foo(Iter b, Iter e) { return X(b, e); // æ æ¨å¯¼ï¼X æ¯å½åç X<T> } template<class Iter> auto bar(Iter b, Iter e) { return X<typename Iter::value_type>(b, e); // å¿ é¡»æå®æéçå®å } auto baz() { return ::X(0); // éæ³¨å ¥ç±»åï¼æ¨å¯¼ä¸º X<int> } };
å¨éè½½å³è®®ä¸ï¼ååºå¨æ¯å¦ä»ç¨æ·å®ä¹æ¨å¯¼æå¼çæå½æ°æ¨¡æ¿é®é¢ä¸æ´ä¼å ï¼è¥ä»æé 彿°çæç彿°æ¨¡æ¿æ¯ä»ç¨æ·å®ä¹æ¨å¯¼æå¼çæè æ´ç¹åï¼å鿩仿é 彿°çæçãå 为å¤å¶æ¨å¯¼åé常常æ¯å è£ æé 彿°æ´ç¹æ®ï¼æ æ¤è§å表æå¤å¶é常æ´ä¼å äºå è£ ã
template<class T> struct A { A(T, int*); // #1 A(A<T>&, int*); // #2 enum { value }; }; template<class T, int N = T::value> A(T&&, int*) -> A<T>; //#3  A a{1,0}; // ä½¿ç¨ #1 æ¨åº A<int> 并以 #1 åå§å A b{a,0}; // ä½¿ç¨ #2ï¼æ¯ #3 æ´ç¹æ®ï¼æ¨åº A<int> 并以 #2 åå§å
å½ä¹åçå³èè§åï¼å æ¬ååºï¼æ æ³å辨两个åé彿°æ¨¡æ¿æ¶ï¼åºç¨ä¸åè§åï¼
- ç±ç¨æ·å®ä¹æå¼çæç彿°æ¨¡æ¿æ¯ä»æé 彿°ææé 彿°æ¨¡æ¿éå¼çæç彿°æ¨¡æ¿æ´åå好ã
- å¤å¶æ¨å¯¼å鿝ææå ¶ä»ä»æé 彿°ææé 彿°æ¨¡æ¿éå¼çæç彿°æ¨¡æ¿æ´åå好ã
- ä»éæ¨¡æ¿æé 彿°å½æ°æ¨¡æ¿ç彿°æ¨¡æ¿æ¯ä»æé 彿°æ¨¡æ¿çéå¼çæç彿°æ¨¡æ¿æ´åå好ã
template <class T> struct A { using value_type = T; A(value_type); // #1 A(const A&); // #2 A(T, T, int); // #3 template<class U> A(int, T, U); // #4 }; // A(A); #5ï¼å¤å¶æ¨å¯¼åé  A x (1, 2, 3); // ä½¿ç¨ #3ï¼ä»éæ¨¡æ¿æé 彿°çæ  template <class T> A(T) -> A<T>; // #6ï¼æ¯ #5 æ´ä¸ç¹æ®  A a (42); // ä½¿ç¨ #6 æ¨åº A<int> 并以 #1 åå§å A b = a; // ä½¿ç¨ #5 æ¨åº A<int> 并以 #2 åå§å  template <class T> A(A<T>) -> A<A<T>>; // #7ï¼ä¸ #5 䏿 ·ç¹æ®  A b2 = a; // ä½¿ç¨ #7 æ¨åº A<A<int>> 并以 #1 åå§å
è¥æ¨¡æ¿å½¢åæ¯ç±»æ¨¡æ¿å½¢åï¼åå°è¯¥å½¢åçæ cv éå®çå³å¼å¼ç¨ä¸æ¯è½¬åå¼ç¨ï¼
template<class T> struct A { template<class U> A(T&&, U&&, int*); // #1ï¼T&& 䏿¯è½¬åå¼ç¨ // U&& æ¯è½¬åå¼ç¨ A(T&&, int*); // #2ï¼T&& 䏿¯è½¬åå¼ç¨ };  template<class T> A(T&&, int*) -> A<T>; // #3ï¼T&& æ¯è½¬åå¼ç¨  int i, *ip; A a{i, 0, ip}; // é误ï¼ä¸è½ä» #1 æ¨å¯¼ A a0{0, 0, ip}; // ä½¿ç¨ #1 æ¨åº A<int> 并以 #1 åå§å A a2{i, ip}; // ä½¿ç¨ #3 æ¨åº A<int&> 并以 #2 åå§å
å½ä»ç±»æ¨¡æ¿æä¸ªç¹åç±»åçå个å®åè¿è¡çåå§åæé®é¢æ¶ï¼é常ä¸é»è®¤çå è£ ç¸æ¯ï¼æ´å好å¤å¶æ¨å¯¼ï¼
std::tuple t1{1}; //std::tuple<int> std::tuple t2{t1}; //std::tuple<int>ï¼é std::tuple<std::tuple<int>>  std::vector v1{1, 2}; // std::vector<int> std::vector v2{v1}; // std::vector<int>ï¼é std::vector<std::vector<int>> (P0702R1) std::vector v3{v1, v2}; // std::vector<std::vector<int>>
é¤äºå¤å¶ VS. å è£ çç¹æ®æ å½¢å¤ï¼å表åå§åä¸ä¿æå¯¹åå§åå¨å表æé 彿°ç强å好ã
std::vector v1{1, 2}; // std::vector<int> Â std::vector v2(v1.begin(), v1.end()); // std::vector<int> std::vector v3{v1.begin(), v1.end()}; // std::vector<std::vector<int>::iterator>
å¨å¼å ¥ç±»æ¨¡æ¿å®åæ¨å¯¼åï¼é¿å æ¾å¼æå®å®åçå¸¸ç¨ææ®µæ¯ä½¿ç¨å½æ°æ¨¡æ¿ï¼
std::tuple p1{1, 1.0}; // std::tuple<int, double>ï¼ä½¿ç¨æ¨å¯¼ auto p2 = std::make_tuple(1, 1.0); // std::tuple<int, double>ï¼C++17 å
ç¼ºé·æ¥å
ä¸åæ´æ¹è¡ä¸ºçç¼ºé·æ¥å追溯å°åºç¨äºä»¥ååºçç C++ æ åã
| DR | åºç¨äº | åºçæ¶çè¡ä¸º | æ£ç¡®è¡ä¸º |
|---|---|---|---|
| P0702R1 | C++17 | åå§åå¨å表æé 彿°è½æ¶ç©ºå¤å¶æ¨å¯¼åéï¼å¯¼è´äº§çå è£ | å¤å¶æ¶è·³è¿åå§åå¨åè¡¨é¶æ®µ |