KDPVã®ä»£ããã«-å®éã®ã€ãã³ãã«åºã¥ããŠæ³šç®ãéããããã®çããã©ãã ãããå®å
šã«ã¹ãããããŠèšäºã«ç§»åã§ããŸããããã¯ãå³èŸºå€ãªã³ã¯ã®çè§£ãã³ã³ã¹ãã©ã¯ã¿ãŒã®ç§»åããŠãããŒãµã«ãªã³ã¯ãå®å
šãªè»¢éãªã©ã«åœ¹ç«ã¡ãŸãã
3å¹ã®ãã©ã
ã¢ã¯ã·ã§ã³1
ã³ã³ãã€ã© ã¹ã¿ãã¯ã«äœãã§ããã¿ã€ãTã®ããŒã«ã«ãªããžã§ã¯ãxã¯ãæ®ãã®äººçã§ã¯äœ¿çšããªããšããäºå®ã«ããããã¹ãŠã®ããããã£ã奪åããããã«å®£åãããŸãã
ãªããžã§ã¯ãx ãªã«ïŒ ç§ã¯ããã«äžæçãªãªããžã§ã¯ãã§ã¯ãããŸãããç§ã¯æ°žç¶çãªç»é²ãæã£ãŠããŸããããªãã«ã¯æš©å©ããããŸããïŒ
ã³ã³ãã€ã© 誰ãããªãã远æŸããŸããã ããããæšæºã³ãŒãã®ç¬¬11çã«ããã°ããã¹ãŠã®ãã®ã¯ãããããããã«å¿
èŠãšããå¥ã®ãªããžã§ã¯ãã«è»¢éãããŸãã
ãªããžã§ã¯ãx ãããŠãã©ããã£ãŠãããããŸããïŒ ãã¹ãŠã®ããŒã¿ã¯å®å
šã«ã«ãã»ã«åãããŠãããããã ãããããäžåœã«åŠçããããšã¯ã§ããŸããã æ¬åœã«ãããªã«å¿
èŠãªå Žåã¯ãã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã«ãã©ãã·ã¥ãã©ã€ããä»å±ãããŠãã³ããŒããŸãã
ã³ã³ã¹ãã©ã¯ã¿ãŒ ã é·ããŠéå¹ççã§ãã
ãªããžã§ã¯ãx ãã¶ããããªãã¯reinterpret_castã§ç§ã®çªãå£ããæéã®äžã§mmããŸããïŒ
ã³ã³ãã€ã© ããããããªãã®ã±ãŒã¹ã¯ã³ã¬ã¯ã¿ãŒã®ãµãŒãã¹ã䜿çšããã«ã¯ããŸãã«ãæ®éã§ãã std :: move颿°ãåŒã³åºãã ãã§ãstatic_cast <T &&>ãèšå®ããã誰ããäžæãªããžã§ã¯ããã€ãŸãå³èŸºå€åŒã§ãããšã¿ãªãããŸãã
ãªããžã§ã¯ãx ããã§ãstatic_castã¯ç§ã«äœã®åœ±é¿ãäžããŸããã ç¶æ¿ã®æåã®ãã€ã³ãã«å°éãããããã«åé€ããŸãã
ã³ã³ãã€ã© ç§ã¯çãäœå°ã¯ãããŸãããããããè¡ãåã«ãããªãã¯ãã§ã«ãã¢ã®å€ã§åŸ
ã£ãŠããéåã³ã³ã¹ãã©ã¯ã¿ãŒã«äŒããŸãã ããªãã¯åœŒã«äŒãæéããªãã£ãããã§ã...
ã¢ã¯ã·ã§ã³2
TïŒT &&ïŒ ã ããã«ã¡ã¯ãäžæãªããžã§ã¯ãïŒ
ãªããžã§ã¯ãx ãããããããç§ã¯å·ŠèŸºå€ã§ãã
TïŒT &&ïŒ ã 誰ããããèšããŸãã ããŠãããªãã¯äœãæã£ãŠããŸããïŒ ããã«æ¥ãŠ...
第3å¹ïŒãšãããŒã°ïŒ
TïŒå®æ°TïŒïŒ ç§ã¯ããªãã®æŽåçãªæ¹æ³ã«æºè¶³ããŠããŸããã
TïŒT &&ïŒ ã ããªãã¯èªåŒµããèªåã§èããŠãã ãããæ»ã«ãããŠãããªããžã§ã¯ãã¯ãªããã®ãžã£ã³ã¯ããã¹ãŠå¿
èŠãšããã®ã§ããïŒ ãããç§ã«ãšã£ãŠã§ãªããã°ãé·ãã³ããŒãäœæãããã¹ãã©ã¯ã¿ã¯ãªãªãžãã«ãç Žå£ããŠããã§ãããã ãã«ã
TïŒå®æ°TïŒïŒ ããã§åœŒã¯åãã€ããªãã£ãã®ãããããŸããã
TïŒT &&ïŒ ã ããã¯ç§ã«éãã¯ãããŸããã ã ãã誰ãããããå¿
èŠã ãšæ±ºããã ãã¹ãŠãåæ³ã§ããç§ã¯ã¡ããã©ç§ã®ä»äºãããŠããŸãã
TïŒå®æ°TïŒïŒ ãããã以åã¯ãããªããããªããŠãããŸããããŸããã ã©ããããããã圌ãã¯è»¢éãšæ»ããæŽçããããåçã¡ã¢ãªå
ã®ç掻空éããªããžã§ã¯ãã«å²ãåœãŠãŸããã ã¯ããã³ã³ãã€ã©ã¯æé©åãæ¯æŽããŸããã
TïŒT &&ïŒ ã ãŸãããã®ãã¹ãŠã®å®å䞻矩ãèŠããŠãããŠãã ããã ãªããžã§ã¯ããç§»å
¥ãããç»é²èšé²ããã¹ãŠå€±ãããåœŒã¯æåŸãŸã§ããã«äœãã§ããããããã远ãæãããšã¯ããªãã£ãã ãããã®ãªããžã§ã¯ãããã§ã«åŸæããã®ã«ååãªå Žåãããã§ãªããã°ããªãã¯ç§ã®å
åŒTïŒconst T &&ïŒã«å€ãããŸã-圌ã¯ããã«æãããããããŸãã ç§ã¯åœŒã«èšããŸããïŒãããã§ããªããžã§ã¯ãã¯ãã¯ãããã³ãã§ã¯ãªããåœŒã®æã¡ç©ãæã¡ãŸããããããŠåœŒã¯ãããäžå¿«ã ãšèšã£ãŠããããã³ããŒããŸãããã
TïŒå®æ°TïŒïŒ ç§ã«ã¯ãæ¬åœã®å¶æªç¯ã§ããå
åŒTïŒTïŒïŒãããŸãã ããã¯ãã³ããŒã³ã³ã¹ãã©ã¯ã¿ãšããŠãç§ã«ãªãããŸããŸã... ãããŠãæ ãæãã€ããŸãã
ãŸããã
æ°ããæŠå¿µã¯å¿
ãããé ã«ãŽã£ããåãŸããšã¯éããŸããã å³èŸºå€ãªã³ã¯ã§ç§ã«èµ·ãããŸããã ãã¹ãŠãéåžžã«åçŽã§ããã®å€èгã®åææ¡ä»¶ã¯æç¢ºã§ããããã«èŠããŸãããããŸããŸãªãã³ãã¬ãŒãã«å
ãŸããããŸããŸãª&&ã§é£œåããã³ãŒããèªã¿åãããšãããšãäžè¬ã«äœãçè§£ããŠããªãããšãããããŸãã
ãã®ãããã¯ã®ç ç©¶ã«ãããç§ã®ééãã¯ãå³èŸºå€ãªã³ã¯ãæ ¹æ¬çã«æ°ãããšã³ãã£ãã£ãšããŠè¡šããããšã§ãã ãããããããã¯å¥åŠã«æãããããããŸããããã¹ãŠã®ããã¥ã¢ã«ã«ã¯ãããã¯åãªãå³èŸºå€ãžã®åç
§ã§ãããšæç¢ºã«æžãããŠããããã§ãã ããã£ãã ããããçµå±ã®ãšããããŠãããŒãµã«ãªã³ã¯ãå®å
šãªè»¢éãªã©ãå€ãã®æ°ããæŠå¿µãããããšå
±ã«ç»å ŽããŸããã ãŸãã&&ãè¿ã颿°ãåŒã³åºããšãããçš®ã®ç¥ç§çãªxvalueåŒã«ãªããŸãã èŠããã«ãããããéåžžã®ãªã³ã¯ãšèŠãªãã®ã¯ç°¡åãããã§ãããã
ã ãããæãéèŠãªããš-è€éã«ããªãã§ãã ããïŒ T&& ref = foo()
ãèŠãããçŸåšrefã«é¢é£ä»ããæ¹æ³ãããããªãå Žåãå³èŸºå€ãžã®å€ãè¯ã宿°åç
§ãšããŠæ±ããŸãïŒ const T& ref = foo()
ãconstãªãã®ã¿ã
ãããŠããªãããã ãã§å³èŸºå€ãžã®ãªã³ã¯ãåãããšãèš±ãããªãã£ãã®ã§ããããïŒ ããããªããšãåŒã巊蟺å€ã§ãããå³èŸºå€ã§ãããã«é¢ããæ
å ±ãããã«å€±ãããŸãã ããã§ãå³èŸºå€ã¯åŒæ°T &&ã§é¢æ°ã«æž¡ããã巊蟺å€ã¯TïŒã§æž¡ãããããã«ãªããŸãã ããã«ããããªããžã§ã¯ããããŸããŸãªæ¹æ³ã§åŠçã§ããããã«ãªããŸããããã¯ãã³ããŒããã³ç§»åã³ã³ã¹ãã©ã¯ã¿ãŒã®å®è£
ã«ãšã£ãŠç¹ã«éèŠã§ãã
ç§ã®ãã1ã€ã®ééãã¯ãVisual Studioã®äŸã確èªããããšã§ãã èšäºå
ã®äŸãããšãã°std::string &str = std::string("42")
ãããã¯ã³ã³ãã€ã«ããªãã§ãç§ãšäžç·ã«ã³ã³ãã€ã«ããŸãã ããã¯ãVisual Studioã®éæšæºã®èšèªæ¡åŒµæ©èœã«ãããã®ã§ãã VSãéçºç°å¢ã§ããå Žåããã®åäœãçè§£ããããšã¯éåžžã«éèŠã§ãããããããã«ã€ããŠè©³ãã説æããŸãã
ãã®èšäºãèªãæè¯ã®æ¹æ³ã¯ãç§ãä¿¡ããªãã§ãèªåã§ãã¹ãŠããã§ãã¯ããããšã§ãã ãããã°ã¢ã»ã³ããªã§ã¢ããã€ã¹ããŸãã GCCã䜿çšããå Žå-fno-elide-constructors
ã¹ã€ããã-fno-elide-constructors
å¯èœãªéãã³ããŒããã³ç§»åã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒã³åºããæå¶ããCopy Elisionãã¯ããã¯ããªãã«ããããšããå§ãããŸãã VSã®å Žåãéæšæºã®æ¡åŒµæ©èœã®äœ¿çšããã£ããããããã«ã第4ã¬ãã«ã®èŠåããªã³ã«ããŸãã
ã¯ããã«
å³èŸºå€ãªã³ã¯ãåŠç¿ããã³ã³ã¹ãã©ã¯ã¿ãç§»åãããšãå€ãã®å Žåãåæ§ã®äŸã«åºãããããšããããŸãã
Matrix m = m1 * m2; std::string s = s1 + s2; std::vector<BigInt> primes = getAllMersennePrimes();
äžæãªããžã§ã¯ããã³ããŒãããããã«ç Žæ£ãããŸãã ãã¡ãããããã¯æããã«åé·ãªæäœã§ãããã ãŒãã³ã³ã¹ãã©ã¯ã¿ãŒã®åäœã¯ããã§ã¯ããªãæçœã§ãã ãã ããã¯ã©ã¹ã«ç§»åã³ã³ã¹ãã©ã¯ã¿ãŒã远å ãããšãå éã«æ°ä»ããªãå ŽåããããŸãã çµå±ãã³ã³ãã€ã©ãŒã¯ããŸããŸãªæé©åææ³ãç¹ã«Return Value Optimizationã䜿çšããŸããããã«ã€ããŠã¯ãèšäºã®æåŸã§å°ã説æããŸãã 以äžã®äŸãæäŸããŸãã 倧ããªããŒã«ã«ãã¯ãã«ãå¡ãã€ã¶ãããšæ³åããŠãã ããã
std::vector<int> items(1000000); fill(items);
ã¡ã¢ãªå
ã§ã¯ã次ã®ããã«ãªããŸãïŒäºçŽæžã¿ã¡ã¢ãªã®æåŸãžã®3çªç®ã®ãã€ã³ã¿ã§ã¹ããŒã ãåè€éåããªãã§ãã ããïŒã

ãããŠãã»ãã¿ãŒãä»ããŠãªããžã§ã¯ãã«ãããæž¡ããŸãã
storage->setItems(items);
以åãšåãããã«ããã¯ãã«ã¯å®æ°åç
§ïŒå·ŠèŸºå€ãšå³èŸºå€ã®äž¡æ¹ã䜿çšã§ããããã«ããïŒãä»ããŠæž¡ãããã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºãããåã倧ããªãã¯ãã«ãäœæãããŸããã ãŸãããªãªãžãã«ã¯ã¹ã³ãŒããåºãåŸã«ã®ã¿åé€ãããŸããã æ°ãããã¯ã¿ãŒã«ããŒã¿ãã€ã³ã¿ãŒãæž¡ãã ãã§ãã

ç°¡åã§ãïŒ
std::vector<int> items(1000000); fill(items); storage->setItems(std::move(items));
ãããŠãsetItemsã¡ãœããã§ïŒ
Storage::setItems(std::vector<int> items) { items_ = std::move(items); }
ãã¯ãã«ã¯å€ã§æž¡ãããããšã«æ³šæããŠãã ãããããã«ããã巊蟺å€ã®ã³ããŒãšå³èŸºå€ïŒç¹ã«äžæãªããžã§ã¯ãïŒã®ç§»åãå¯èœã«ãªããŸãã ãããã£ãŠãããŒã«ã«ãã¯ãã«ããŸã å¿
èŠãªå Žåã¯ãstd :: moveã䜿çšããã«setItemsãåŒã³åºãã ãã§ãã å°ããªãªãŒããŒãããã¯ãåŒæ°ãç§»åæŒç®åã䜿çšããŠåã³ç§»åãããããšã§ãã
åæå
ãã¹ãŠã®æŠå¿µã«å¯ŸåŠããããã«å¿
èŠãªããšã¯ãåæåã®ããŸããŸãªæ¹æ³ã«éäžããããšã ãã§ãã ããã¯å€æ°ã®åæåãããããŸããïŒ
T x = expr;
åŒæ°ãæž¡ãïŒ
void foo(T x); foo(expr);
æ»ãå€ïŒ
T bar() { return expr; }
ãããã®ãã¹ãŠã®ã±ãŒã¹ã¯ãæå³çã«åäžã§ãããããåæåãšåŒã°ããŸãã æ¬¡ã«ãã¿ã€ãT
æ€èšããŸãT
次ã®ããããã«ãªããŸãã
- åç
§ãªãã¿ã€ãïŒAïŒ
- 巊蟺å€åç
§ïŒAïŒïŒ
- å³èŸºå€åç
§ïŒA &&ïŒ
ãã€ã³ã¿ãŒã®ããåã¯ãããã®1ã€ãæãããšãæç¢ºã«ããŸãã ããšãã°ã A*
ã¯åç
§ãªãã®ã¿ã€ãã A*&
ã¯å·ŠèŸºå€åç
§ãªã©ã§ãã æ¬¡ã«ãåŒexpr
泚æããŠãã ããã åŒã«ã¯ãå€ã®ã¿ã€ããšã«ããŽãªïŒå³èŸºå€ãŸãã¯å·ŠèŸºå€ïŒããããŸãã 衚çŸã®ã¿ã€ãã¯ãç§ãã¡ãèããã»ã©éèŠã§ã¯ãããŸããã ãã®ãããã¯ã§ã¯ãäž»ãªåœ¹å²ã¯åŒã®å€ã®ã«ããŽãªïŒå³èŸºå€ãŸãã¯å·ŠèŸºå€ïŒã«ãã£ãŠæããããŸããç°¡ç¥åã®ãããåŒã®ã«ããŽãªãšåŒã°ããŸãã
ãããã£ãŠãå·ŠåŽã«3ã€ã®ãªãã·ã§ã³ããããå³åŽã«2ã€ã®ãªãã·ã§ã³ããããŸãåèš6.ãã詳现ã«èª¿ã¹ãåã«ãã«ããŽãªã®å®çŸ©æ¹æ³ãåŠç¿ããŸãã
åŒã®å€ã®ã«ããŽãª
巊蟺å€ãšå³èŸºå€
C ++ 11ããåã¯ãããã2ã€ã®ã«ããŽãªã®ã¿ãååšããŠããŸããã ç§»åã»ãã³ãã£ã¯ã¹ã®åºçŸã«ãããå³èŸºå€ã«ããŽãªã¯ããã«2ã€ã®ã«ããŽãªã«åé¡ãããŸãããããã«ã€ããŠã¯ã次ã®ãµãã»ã¯ã·ã§ã³ã§èª¬æããŸãã ãããã£ãŠãååŒã®ã«ããŽãªã¯å·ŠèŸºå€ãŸãã¯å³èŸºå€ã§ãã ãã¡ãããæšæºã¯ãããã®ããããã«é©çšããããã®ã説æããŠããŸãããèªãããšã¯å°é£ã§ãã
ã¹ã³ãããã€ã€ãŒãºã¯æ¬¡ã®ã«ãŒã«ãæäŸããŠããŸãã
- åŒã®ã¢ãã¬ã¹ãååŸã§ããå Žåãããã¯å·ŠèŸºå€ã§ãã
- ãã以å€ã®å ŽåãåŒã®åã巊蟺å€åç
§ïŒã€ãŸããTïŒãŸãã¯const TïŒãªã©ïŒã§ããå Žåãããã巊蟺å€ã§ãã
- ãã以å€ã®å ŽåãåŒã¯å³èŸºå€ã§ãã
圌ãã¯å³å¯ã§ã¯ãªãã®ã§ãç§ã¯åœŒããæ¬åœã«å¥œãã§ã¯ãããŸããããããŠæã
å€ããå€ãã®åŸ®åŠãããããŸãã ãããŠãæãéèŠãªããšã¯ããããã¯ãå匷ãããšããã¢ãã¬ã¹ãåãããšãå¯èœãã©ãããã©ã®ããã«çè§£ã§ããŸããïŒ ãŸãããŸããç§ãã¡ã¯äžæãªããžã§ã¯ããã§ããªãããšãç¥ã£ãŠããŸãã str
ã©ãã§ããïŒ
std::string &&str = std::string("Hello"); std::string *psrt = &str;
ãã®åã¯å³èŸºå€åç
§ã§ããã str
ã¯å·ŠèŸºå€ã§ãããããå¯èœã§ãã ããã¯éèŠã§ãã
å¿
èŠã«å¿ããŠã cppreferenceïŒvalue categoryã«ç®ãåããŸã ãããã§ã¯ãåŒã®ãªã¹ããæäŸãããŸãã ããããããã€ãã®äŸïŒ
- 巊蟺å€ïŒ
- 倿°ãŸãã¯åŒæ°ã®ååïŒãããã®åãå³èŸºå€åç
§ã§ãã£ãŠãïŒã ããšãã°ã
std::cin
ã - æ»ãå€ã®åã巊蟺å€åç
§ã§ãã颿°ãŸãã¯ã¹ããŒãã¡ã³ãã®åŒã³åºãã ããšãã°ã
std::cout << 1
ã ++it
ã§ãã "Hello, world!"
ãªã©ã®æååãªãã©ã« ã
- å³èŸºå€ïŒ
- éæååãªãã©ã«ãäŸãã°
42
ã true
ã nullptr
ã - æ»ãå€ã®åãåç
§ã§ã¯ãªã颿°ãŸãã¯ã¹ããŒãã¡ã³ããåŒã³åºã
- ã¢ãã¬ã¹ãã£ããã£ïŒ
&a
ã - æ»ãå€ã®åãå³èŸºå€åç
§ã§ãã颿°ãŸãã¯ã¹ããŒãã¡ã³ãã®åŒã³åºãã ããšãã°ã
std::move(x)
ã am
ãããã§aã¯å³èŸºå€ã§ãã
xvalueãprvalueãããã³glvalue
æ¢ã«è¿°ã¹ãããã«ãå³èŸºå€ã¯xvalueïŒeXpiring巊蟺å€ïŒãšprvalueïŒçŽç²ãªå³èŸºå€ïŒã®2ã€ã®ã«ããŽãªã«åé¡ãããŠããŸãã ãããŠãxvalueãšãšãã«lvalueã¯glvalueïŒäžè¬åããã巊蟺å€ïŒãšããŠç¥ãããããã«ãªããŸããã ããã§ãæé«ã®ç²ŸåºŠãåŸãã«ã¯ã3ã€ã®ã«ããŽãªã®ããããã«åŒãå²ãåœãŠãå¿
èŠããããŸãã å³ã§ã¯ã次ã®ããã«ãªããŸãã

次ã®åŒãxvalueã«é©çšãããŸãã
- æ»ãå€ã®åãå³èŸºå€åç
§ã§ãã颿°ãŸãã¯ã¹ããŒãã¡ã³ãã®åŒã³åºãã ããšãã°ã
std::move(x)
ã am
ãããã§aã¯å³èŸºå€ã§ãã
ãªã远å ã®ã«ããŽãªãå¿
èŠãªã®ã§ããïŒ xvalueåŒã¯å³èŸºå€ã§ãããããã€ãã®å·ŠèŸºå€ããããã£ããããŸããããšãã°ãããªã¢ãŒãã£ãã¯ã§ãã ããã«ããããã®è¿œå ã®ã«ããŽãªã¯å¿
èŠãããŸããããçœç±ããè°è«ã®äžã§æš©éãé«ããã®ã«åœ¹ç«ã¡ãŸãã
åæåã¡ãœãã
æšå®ã§ã¯ã6ã€ã®ãªãã·ã§ã³ãåºãŠããŸããã å®éã«ã¯ã3ã€ã ããèæ
®ããå¿
èŠããããŸããæåã«ã巊蟺å€åŒã§å³èŸºå€ãªã³ã¯ãåæåã§ããªãããã§ãã ãããŠæ¬¡ã«ãããåŒã«ãããªããžã§ã¯ãïŒéåç
§åïŒã®åæåã¯ãã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããŠããŸãã¯åç
§ã«ãã£ãŠåŒãïŒã³ã³ã¹ãã©ã¯ã¿ãŒã«ïŒæž¡ãããšã«ãã£ãŠç§»åããŸãã æåã®ã¬ã€ããšããŠããã®ãããªã¹ããŒã ïŒ

TïŒx =巊蟺å€
ãã¬ãŒã³ãªã³ã¯ã
TïŒx =å³èŸºå€
ããã¯2ã€ã®å Žåã«ã®ã¿æ©èœããŸãã
ã±ãŒã¹1.äžå®ã®åç
§çš
const T& x = rvalue;
c ++ 11ããåã¯ããããäžæãªããžã§ã¯ããã©ããã«æž¡ãå¯äžã®æ¹æ³ã§ããã ããšãã°ãã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã®å ŽåïŒ
T::T(const T&); T x = T();
ãŸãã¯ä»ã®å ŽæïŒ
void readFile(const std::string &); std::string filename = "data"; readFile(filename + ".txt");
ãåç¥ã®ããã«ã宿°åç
§ã¯äžæãªããžã§ã¯ãã®å¯¿åœãå»¶ã°ããŸãã ã¯ãããã ãããã®ãªã³ã¯ããŸã ã¹ã³ãŒãå
ã«ããå Žåã®ã¿ã§ãã äžæãªããžã§ã¯ãã¯ã¹ã¿ãã¯äžã«ãããããã¹ã³ãŒããŸãã¯é¢æ°ãé¢ãããšããã³ã³ãã€ã©ãŒã¯ãªããžã§ã¯ãã®éåœã«è²¬ä»»ãæã€å¿
èŠããªããªããŸãã
ã±ãŒã¹2. Visual Studioã§
Visual Studioã§æ£åžžã«åäœããäŸã«é©ããªãã§ãã ããã
std::vector<int> &v = std::vector<int>({ 1, 2, 3 }); v.push_back(4);
çãã¯ãèŠåã¬ãã«4ã§ã®ã¿è¡šç€ºãããŸãã
warning C4239: nonstandard extension used note: A non-const reference may only be bound to an lvalue
ãã®éæšæºã®C ++æ¡åŒµæ©èœã¯/Za (Disable Language Extensions)
ã¹ã€ããã«ãã£ãŠ/Za (Disable Language Extensions)
ã«ãªã£ãŠããŸããã Windows.h
ãªã©ã®äžéšã®ããããŒã¯æ¡åŒµæ©èœã«å«ãŸããŠãããããã³ã³ãã€ã«ãããŸããã
T && x =巊蟺å€
ç°¡åã§ãããã®ããã«æžãããšã¯ã§ããŸããã æ³šæããŠãã ãããHabréã«ã¯ããRvalue Referencesã®ç°¡åãªç޹ä»ãïŒ2008幎ãŸã§ã®èšäºïŒã®ç¿»èš³ããããŸããããã¯ããrvalueãã®æ€çŽ¢ãšã³ãžã³çµæã®æåã®ãã®ã§ãã ããããã®äŸã¯ééã£ãŠããŸãïŒ
A a; A&& a_ref2 = a;
ãŸãã std::move
誀ã£ãå®è£
ããããŸãã ãã ããã³ã¡ã³ãã¯ãšã©ãŒã瀺ããŠããŸããã
T && x =å³èŸºå€
æãè峿·±ããã®ã«å°éããŸããã æãåçŽãªäŸããå§ããŸãããã
std::string foo(); std::string&& str = foo(); int&& i = 5;
ãããã®ãªã³ã¯ã¯éåžžã©ããåäœããŸãã 倿Žå¯èœãªconst TïŒãªã³ã¯ãæ³åããããVisual Studioæ¡åŒµæ©èœãèŠããŠãããŠãã ããã åé¡ãçºçããå¯èœæ§ããããŸãããªãããã¹ãŠã®ã«ããŽãªã®è¡šçŸã«éåžžã®ãªã³ã¯ã䜿çšã§ããªãã®ã§ããïŒ VSã§ã¯ãããã¯ããŸãæ©èœããŸããïŒã¯ã©ã¹çšïŒã &&ãªã³ã¯ã䜿çšãããšãåŒã®ã¿ã€ãã ãã§ãªããã«ããŽãªïŒå·ŠèŸºå€ãŸãã¯å³èŸºå€ïŒã«ãã£ãŠé¢æ°ãç¹ã«ã³ã³ã¹ãã©ã¯ã¿ãŒããªãŒããŒããŒãã§ããŸãã 2ã€ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã®äŸïŒ
string(const string&); string(string&&); string s1 = "Hello "; string s2 = "world!"; string s3 = s1 + s2;
åŒs1 + s2
ã¯å³èŸºå€ã§ãããäž¡æ¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒãããã«é©ããŠããŸãïŒã»ã¯ã·ã§ã³ã®åé ã®å³ãåç
§ïŒã ã¿ã€ãæåå&&ãåªå
ãããŸãã ç§»åã³ã³ã¹ãã©ã¯ã¿ãŒã«ç²ŸéããŠãã人ã¯ããããéèŠãªçç±ãç¥ã£ãŠããŸãã ããã«ã€ããŠè©³ãã説æããåã«ãåªå
é äœãçè§£ããŸãã
åªå
é äœ
ã»ãšãã©ã®å Žåã T&&
ãåªå
床T&&
é«ãã const T&
ããšãç¥ãã ãã§ååã§ãã ãããã const T&&
ãšT&
äž¡æ¹ãæ±ãããšããå§ãããŸãã æ¡åŒµå³ã¯æ¬¡ã®ãšããã§ãã

ã«ãŒã«ã¯åçŽã§ãïŒåªå
é äœã®éé ïŒïŒ
- ãŸã第äžã«ãlikeã¯å¥œãã«ãªãåŸåããããŸãïŒæ°Žå¹³ç¢å°ïŒã
- 宿°ãªãã·ã§ã³ãé©ããŠããŸãã
- ãããŠãä»ã®ãã¹ãŠã®ãªãã·ã§ã³ãååšããªãå Žåã
const T&
åã¯ãã¹ãŠã®åŒã«é©çšãããŸãã - VSã®å ŽåïŒå³èŸºå€ïŒç Žç·ç¢å°ïŒãžã®é宿°ãªã³ã¯ãå¿ããªãã§ãã ãã ã
ã³ã³ã¹ãã©ã¯ã¿ã®ã³ããŒãšç§»åïŒT x =巊蟺å€; T x =å³èŸºå€;ïŒ
ããªããæžããšãïŒ
T x = expr;
ã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºãããŸãã ã©ã£ã¡ïŒ ã¯ã©ã¹ã«ã¯è€æ°ã®ãã®ããããŸãã
T(const T&);
ã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºããããšãåŒã®ã«ããŽãªãšåŒæ°ã®ãªã³ã¯ã®ã¿ã€ãã«å¿ããŠãäžèšã®ã¹ããŒã ã«åŸã£ãŠåç
§ã«ãã£ãŠåŒã転éãããŸãã æ¬¡ã«ãåã³ã³ã¹ãã©ã¯ã¿ãŒã®æ©èœã«ã€ããŠèª¬æããŸãã
1. TïŒå®æ°TïŒïŒ
éåžžã®ã³ããŒã³ã³ã¹ãã©ã¯ã¿ã åªå
åºŠã¯æäœã§ãããä»»æã®åŒãåãå
¥ããããšãã§ããŸãã
2. TïŒTïŒïŒ
æåã¯äžå®ã§ãªããã°ãœãŒã¹ãç°¡åã«å€æŽã§ãããããç§ã¯ãããitãªã³ããŒã³ã³ã¹ãã©ã¯ã¿ãšåŒã³ãŸãã éåžžã®ã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒãããåªå
ãããŸãã å®éã«äœ¿çšãããŠãããšã¯æããŸããã ãã®äœ¿çšäŸãããã°ãæžããŠãã ããã
3. TïŒå®æ°T &&ïŒ
ããã¯å³èŸºå€åŒãã€ãŸã寿åœãçµäºãããªããžã§ã¯ããåãããšãã§ããŸãã æ»ã«ãããŠãããªããžã§ã¯ãã¯èšããŸãïŒç§ã¯æ»ã«ãããŠããŸã æg匟 ããŒã¿ãžã®ãã€ã³ã¿ãŒãç§ã¯ãã¯ãããããå¿
èŠãšããŸããã ãããŠãã³ã³ã¹ãã©ã¯ã¿ãŒã¯çããŸãïŒããããç§ã¯ãããããããšãã§ããŸããã圌ãã¯ããªãã®ãã®ã§ãããããªããšäžç·ã«ããŸããç§ã¯ã³ããŒãäœãããšãã§ããã ãã§ãã ãŸããç§ã¯å®çšçãªãŠãŒã¹ã±ãŒã¹ãç¥ããŸããã
4. TïŒT &&ïŒ
ãã®ã³ã³ã¹ãã©ã¯ã¿ã¯ã宿°ã§ãªãå³èŸºå€ã«å¯ŸããŠã®ã¿åŒã³åºãããŸãã ãã®ãããªåŒã¯ãäžæãªããžã§ã¯ããŸãã¯static_cast<T&&>
ã䜿çšããŠå³èŸºå€åç
§ã«ãã£ã¹ãããããªããžã§ã¯ãã§ãã ãã®ãããªå€æã¯ãªããžã§ã¯ãã«ã¯ãŸã£ãã圱é¿ããŸãããããã®ãããªã©ãããŒåŒã¯ãå³èŸºå€åç
§ã«ãã£ãŠmoveã³ã³ã¹ãã©ã¯ã¿ãŒïŒãŸãã¯äœããã®é¢æ°ïŒã«æž¡ãããšãã§ããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãããŒã¿ããã³ã¯ã©ã¹ã®ä»ã®ã¡ã³ããŒãžã®ãã¹ãŠã®ãã€ã³ã¿ãŒãååŸããããããæ°ãããªããžã§ã¯ãã«æž¡ããŸãã ãããã£ãŠãã ãŒãã³ã³ã¹ãã©ã¯ã¿ãŒã®å¹æçãªäœæ¥ã«ã¯ãã¯ã©ã¹ã¡ã³ããŒã®æ°ãæžããå¿
èŠããããŸãã æ¥µç«¯ãªå Žåãå®è£
ãžã®ãã€ã³ã¿ã¯1ã€ããä¿åã§ããŸããã Pimplã®ã€ãã£ãªã ïŒå®è£
ãžã®ãã€ã³ã¿ãŒïŒãããã§é©ããŠããŸãã
ããšãã°ãããŒãäžã®ããŒã¿ãžã®ãã€ã³ã¿ãŒãšæååã®é·ãã§æå®ãããæååã®ã¯ã©ã¹ãèããŠã¿ãŸãããïŒããã¯åãªãæŠå¿µçãªäŸã§ãïŒã
class String { char* data_; size_t length_; public: explicit String(size_t length) { data_ = static_cast<char*>(::operator new(length)); length_ = length; } ~String() { ::free(data_); } };
ããã¯ãç§»åã³ã³ã¹ãã©ã¯ã¿ãŒã®ããã«èŠããå ŽåããããŸãã
String(String&& other) { data_ = other.data_;
ããŒã¿ããªã»ããããªãã£ãå Žåã¯ã©ããªããŸããïŒ3-4ã³ã³ã¹ãã©ã¯ã¿è¡ïŒïŒ é
ããæ©ããã2ã€ã®ããã«ãªããžã§ã¯ãã«å¯ŸããŠãã¹ãã©ã¯ã¿ãåŒã³åºãããåãããŒã¿ã2ååé€ããããšããŸãã ããããããŒã¿ãã€ã³ã¿ã®ã¿ããªã»ããããé·ãããªã»ããããªããšã©ããªããŸããïŒ çµå±ããã¹ãã©ã¯ã¿ã¯éåžžã®2ååäœããŸã-ç¹ã«ããã¯é·ãã䜿çšããŸããã ãã®åŸãçªç¶getLength
颿°ã䜿çšãããªããžã§ã¯ãã®ãŠãŒã¶ãŒã¯ã誀ã£ãæ
å ±ãåãåããŸãã ãããã£ãŠãäžèŠã«ãªã£ããªããžã§ã¯ããébarã«æ±ãããšã¯ã§ããŸããã ãããã«ããŠãã空ã®ãŸãŸã«ããå¿
èŠããããŸãããæ£ããç¶æ
ã«ãããŸãã ããã«ãããªãã¯åœŒã®ç涯ãéããŠæ°ååããåŒãèµ·ããããšãã§ããŸãã
static_cast <T &&>ããã³std :: move
ç§»åã³ã³ã¹ãã©ã¯ã¿ãŒã«ã€ããŠè°è«ãããšãããã§ã«static_cast<T&&>
ã«ã€ããŠè©±ãstatic_cast<T&&>
ã æãåºããšã static_cast<T&&>
ã«ãã©ããããããåŒã¯ããªããžã§ã¯ããç§»åã§ããããšã瀺ããŠããŸãã æ¬¡ã«ãæ°ãããªããžã§ã¯ããåæåããããšãã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ãªããç§»åã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºãããŸãã ããã§ãèšäºã®æåããã¿ã¹ã¯ãå®è£
ã§ããŸãã
std::vector<int> items(1000000); fill(items); static_cast< std::vector<int>&& > (items);
ããªãã¯ãããããã£ãšäŸ¿å©ãªæ¹æ³ãããããšãç¥ã£ãŠããã§ããã-颿°std::move
åŒã³åºããããã¯static_castã®ã©ãããŒã§ãã ãããã©ã®ããã«æ©èœããããçè§£ããããã«ãç§ãã¡ã¯ãããèªåã§æžããŠãã¹ãŠã®çæãèžã¿ãŸãããããã¯æçšãªæèšã«ãªããŸãã ããã«èªãåã«ãèªåã§æžãããšãã§ããŸãã ãã¡ããããã®é¢æ°ã¯ãç°ãªãã¿ã€ããåãå
¥ããããã«å®åã§ããå¿
èŠããããŸãã ããããä»ã®ãšãããç°¡åã«ããããã«ãç¹å®ã®ã¯ã©ã¹Aã«å¯ŸããŠ1ã€ãè¡ããŸããæšæž¬ããŸãã 巊蟺å€ãæž¡ãããå Žåãããã¯ã¿ã€ãAïŒã®åŒæ°ã䜿çšããŠã®ã¿å®è¡ã§ããŸãã æ¬¡ã«ããããA &&ã«å€æããæ»ãå€ã®åãA &&ã«ãªããŸãã &&ãè¿ã颿°ã®åŒã³åºãã¯ãå¿
èŠã«å¿ããŠå³èŸºå€åŒïŒããæ£ç¢ºã«ã¯xvalueïŒã§ãã
A&& my_move(A& a) { return static_cast<A&&>(a); }
ããããæšæºé¢æ°std :: moveã¯å³èŸºå€ãåãå
¥ãããããæ®éçã§ãããç§ãã¡ã®ãã®ãšã¯èšããŸããã 1ã€ã®è§£æ±ºçã¯ç°¡åã§ããåŒæ°A &&ã䜿çšããŠå¥ã®é¢æ°ã远å ããŸãã
A&& my_move(A&& a) { return static_cast<A&&>(a); }
巊蟺å€ãšå³èŸºå€ã®äž¡æ¹ã§æ©èœããŸãã ãã ããå®éã®std :: moveã¯1ã€ã ãã§ããã³ãã¬ãŒãåŒæ°ã®åã¯T &&ã§ãã ã©ãããŠïŒ ããã«çè§£ããŸãã
ãªã³ã¯å§çž®ãšãŠãããŒãµã«ãªã³ã¯
ãã®ãããå®åæstd :: moveã¯åŒæ°T &&ã®å·ŠèŸºå€ãåãããšãããããŸããã ãããã£ãŠãT &&ã¯å³èŸºå€åç
§ã§ã¯ãããŸããã T &&ã¯ã©ããããããTïŒã«å€ãã£ãŠããŸãã ããããTã¯ã©ã®ãããªåã§ã€ã³ã¹ã¿ã³ã¹åãããŸããïŒ äœãäœã§ããããçè§£ããããã«ãåŒã®2ã€ã®ã«ããŽãªïŒå³èŸºå€ãšå·ŠèŸºå€ïŒã«å¯ŸããŠ2ã€ã®ãªãŒããŒããŒã颿°ãåŒã³åºããŠã¿ãŸãããã
template<class T> void foo(T&); template<class T> void foo(T&&); A a; foo(a);
颿°èªäœã§ãTãã€ã³ã¹ã¿ã³ã¹åãããã¿ã€ãã確èªããŸãããªã³ã¯ã®ã¿ã€ãã¯æ¬¡ã®ããã«ç¢ºèªã§ããŸãã
bool is_lvalue = std::is_lvalue_reference<T>::value; bool is_rvalue = std::is_rvalue_reference<T>::value;
3ã€ã®ãªãã·ã§ã³ãé©åã§ããããšãããããŸãã
foo(T&)
åŒã³åºããšãã®è¡šèšfoo(lvalue)
ã¯ã foo<T>(lvalue)
ãšåçã§ããfoo(T&&)
åŒã³åºããšãã®è¡šèšfoo(rvalue)
ã¯ã foo<T>(rvalue)
ãšåçã§ããfoo(T&&)
åŒã³åºããšãã®è¡šèšfoo(lvalue)
ã¯ã foo<T&>(lvalue)
ãšåçã§ãã
次ã®å³ã§ã¯ãç¢å°ã®çœ²åã¯ãã©ã®ã¿ã€ãTãã€ã³ã¹ã¿ã³ã¹åããããã瀺ããŠããŸãã

æåã®2ã€ã®ãªãã·ã§ã³ã¯äºæž¬å¯èœã§ããããããã«äŸåããŠããŸããã 3ã€ç®ã¯ãåç
§æãããã¿ã«ãŒã«ã䜿çšããŸãããªã³ã¯å§çž®ã¯ããªã³ã¯ãžã®ãªã³ã¯ã衚瀺ããããšãã®åäœã決å®ããŸãã ãã®ãããªãã¶ã€ã³èªäœã¯çŠæ¢ãããŠããŸããããã³ãã¬ãŒãã§çºçããŸãã ãããã£ãŠãTãA &&ã«ãã£ãŠã€ã³ã¹ã¿ã³ã¹åãããå ŽåãT &&ïŒA && &&ïŒ= A &&ã§ãããä»ã®å ŽåïŒãªã³ã¯ãžã®ãªã³ã¯ïŒã®ã¿ã€ãã¯AïŒã§ããããšã瀺ãããŸããã
T = A& => T& = A& T = A& => T&& = A& T = A&& => T& = A& T = A&& => T&& = A&&
ãããã£ãŠãã¿ã€ãT &&ã®åŒæ°ïŒTã¯ç·ç§°ã¿ã€ãïŒã¯ãäž¡æ¹ã®ã¿ã€ãã®ãªã³ã¯ãåãå
¥ããããšãã§ããŸãã ãããã£ãŠãT &&ãªã©ã®ãªã³ã¯ã¯ã ãŠãããŒãµã«ãªã³ã¯ãšåŒã°ããŸãã
std :: moveïŒç¶ãïŒ
std :: moveã§T &&ã䜿çšã§ããããšã¯æããã§ãïŒäžã®å³ã®fooïŒT &&ïŒãåç
§ïŒã my_moveã«ã¹ãã¬ãªã¿ã€ãã远å ããŸãããã
template<class T> T&& my_move(T&& t) { return static_cast<T&&>(t); }
T &&ã¯å·ŠèŸºå€ã®AïŒã«å€ãããããããã¯èª€ã£ãå®è£
ã§ãããã®å Žåã颿°ã€ã³ã¹ã¿ã³ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
A& my_move(A& t) { return static_cast<A&>(t); }
åŒæ°ã®åã¯æ£ããã§ãããä»ã®å Žæã§ã¯AïŒã§ã¯ãªãA &&ãæ®ãå¿
èŠããããŸããã std :: moveã®å®è£
ãèŠãæéã§ãïŒ
template<class T> typename remove_reference<T>::type&& move(T&& _Arg) { return (static_cast<typename remove_reference<T>::type&&>(_Arg)); }
æç¢ºã ãšæããŸãïŒremove_referenceã¯ãã¹ãŠã®ãªã³ã¯ãåé€ããçµæã®åã«&&ã远å ãããŸãã ãšããã§ãremove_referenceã¯ã©ã¹ã¯éåžžã«åçŽã§ãã ãããã¯ããã©ã¡ãŒã¿ãŒTãTïŒãT &&ãæã€3ã€ã®ãã³ãã¬ãŒãã¯ã©ã¹ã®ç¹æ®åã§ãã
template<class T> struct remove_reference { typedef T type; }; template<class T> struct remove_reference<T&> { typedef T type; }; template<class T> struct remove_reference<T&&> { typedef T type; };
å®å
šè»¢éãšæšæº::転é
ãã¹ãŠã®åé¡ãæŽçããããã«èŠããŸãããããã§ã¯ãããŸããã T &&ãã³ãã¬ãŒãã«åŸã£ãŠãã¹ãŠã®è¡šçŸã転éããããšãåŠã³ãŸããããããããããã«æäœããæ¹æ³ã«ã¯ãŸã èå³ããããŸããã§ããã ããããããšãªããã¹ãŠãå³èŸºå€ã«å°ããããstd :: move颿°ã¯èæ
®ãããŸããã åŒã®ã«ããŽãªãåºå¥ããå¿
èŠãããã®ã¯ãªãã§ããïŒ make_shared
é¡äŒŒç©ãæžããŠãããšæ³åããŠmake_shared
ã make_shared<T>(...)
èªäœããæå®ãããåŒæ°ã§ã³ã³ã¹ãã©ã¯ã¿TãåŒã³åºãããšãæãåºããŸãã ä»ã¯å¯å€é·ãã³ãã¬ãŒããæ±ãæã§ã¯ãããŸããããã®ãããç°¡åã«ããããã«ãåŒæ°ã1ã€ãããªããšä»®å®ããŸãã ãŸããæãäžè¬çãªãã€ã³ã¿ãŒãè¿ããŸãã ç°¡åãªã¯ã©ã¹ãåããŸãïŒ
class A { public: A();
ãããè¡ãããïŒ
A a; A* a1 = make_raw_ptr<A>(a);
ãªã³ã¯å§çž®ã䜿çšããŠãå®è£
ãèšè¿°ããŸãã
template<class T, class Arg> T* make_raw_ptr(Arg &&arg) { return new T(arg); };
ãã¡ãããããŸããããŸãã åžžã«ã³ããŒã®ã¿ãçºçããŸãã ééããèŠã€ããŸãããïŒ åçŽã§ã-argã¯åžžã«å·ŠèŸºå€ã§ãã å
ã®è¡šçŸã®ã«ããŽãªã«é¢ããæ
å ±ã倱ã£ãããã§ãã ããã§ã¯ãããŸãã-ããã¯ãŸã Argããæœåºã§ããŸãã å®éã巊蟺å€ã®å ŽåïŒArg = AïŒãå³èŸºå€ã®å ŽåïŒArg = A ãªã³ã¯ã®ã¿ã€ãã埩å
ãã颿°ãå¿
èŠã§ããããšãããããŸãããã€ãŸããæ¬¡ã®ãšããã§ãã
- ã¿ã€ãAïŒã®å·ŠèŸºå€ãæž¡ããšãAïŒãè¿ããŸã
- ã¿ã€ãAã®å·ŠèŸºå€ãæž¡ããšãA &&ãè¿ããŸã
- å³èŸºå€ãæž¡ããšã...æ°ã«ãªããŸã§ã
A ( ):
, . , A&, A. , A& â A&, A â A&&. , "" &&.
template<class T> T&& my_forward(T& a) { return static_cast<T&&>(a); } template<class T, class Arg> T* make_raw_ptr(Arg &&arg) { return new T(my_forward<Arg>(arg)); };
std::forward . & &&, .
/ , , . move-. . GCC -fno-elide-constructors
. , .
.
T foo() { T result; return result; } foo();
foo . , . , , :
T temp = result;
, , . temp â , . , result, , rvalue, foo. temp . , ( & &&) .
, :
T x = foo();
:
T temp = result;
. , .
, ( , sizeof, ), .
Copy elision return value optimization
C++ : ? std::vector<int> get();
void get(std::vector<int> &);
move- . copy elision â , . , return value optimization (RVO). ( ), , . , , . RVO? Visual Studio 2015:
T foo() { return T(); } class T { public: T() = default;
, . , , . std::shared_ptr std::unique_ptr.