ææžã®äžèŠ§
SG22ã®WG14ããã®ãã®ãé€ããŠãå šéšã§84æ¬ãããŸãã
[:contents]
C++23ã®ã¯ãŒãã³ã°ãã©ãã第8匟ã
âã®å€æŽç¹ããŸãšããææžã
11æã®KonaäŒè°ã§æ¡æãããææ¡ãšã³ã¢èšèª/ã©ã€ãã©ãªã®Issue解決ãé©çšãããŠããŸãã
2022幎11æ7-12æ¥ã«ãã¯ã€ã®Konaã§è¡ããããWG21å šäœäŒè°ã®è°äºé²ã
éå¬æéäžã®åã°ã«ãŒãã®æŽ»åå ±åããCWG/LWG/LEWGã®æ祚ã®æ§åãªã©ãèšèŒãããŠããŸãã
2023幎ïŒä»å¹ŽïŒã®WG21管çè ããŒãã£ã³ã°ã®äºå®è¡šã
2023幎6æã«ãã«ã¬ãªã¢ã®ãŽã§ã«ãã§éå¬ãããäºå®ã®WG21å šäœäŒè°ã®ã€ã³ãã©ãŒã¡ãŒã·ã§ã³ã
äž»ã«éå¬å Žæããã®æ³šæç¹ãªã©ãèšèŒãããŠããŸãã
2023幎11æã«ãã¯ã€ã®Konaã§éå¬ãããäºå®ã®WG21å šäœäŒè°ã®ã€ã³ãã©ãŒã¡ãŒã·ã§ã³ã
åäžã
次ææšæºã©ã€ãã©ãªæ©èœåè£ã®å®è£ çµéšãåŸãããã®TSã§ãããLibrary Fundamental TS v3ã®FDISã
次ææšæºã©ã€ãã©ãªæ©èœåè£ã®å®è£ çµéšãåŸãããã®TSã§ãããLibrary Fundamental TS v3ã®ãã©ããææžã
ããããå 容ã¯N4937ãšåäžã§ãã
âã®å€æŽç¹ãèšããææžã
ãã®çã§ã®å€æŽã¯ãtypoã®ä¿®æ£ãªã©ã§ãã
æšæºã©ã€ãã©ãªã«äžŠè¡ãã¥ãŒãè¿œå ããããã®èšèšãç·Žãææ¡ã
ãã¥ãŒã¯ã·ã¹ãã ã³ã³ããŒãã³ãéã®ããŒã¿ã®ããåãã®æ¹æ³ãæäŸããåºç€çãªãã®ã§ããçŸåšã®C++æšæºã©ã€ãã©ãªã«ãstd::deque
ãªã©ãçšæãããŠããŸããããããã¯å
šãŠã·ãŒã±ã³ã·ã£ã«ãªããŒã¿æ§é ã§ããããã®èŠçŽ ã¢ã¯ã»ã¹ãšãã¥ãŒã®æäœã䞊è¡ã«è¡ãããšãã§ããŸããããã®ããã䞊è¡ãã¥ãŒãå°å
¥ããããã«ã¯ãããããšã¯å¥ã®ãã®ãå¿
èŠãšãªããŸãã
ããã«ã䞊è¡æ§ã®èŠæ±ã¯ããã©ãŒãã³ã¹ãšãã®ã»ãã³ãã£ã¯ã¹ã«æ°ããªè©äŸ¡è»žãè¿œå ãã䞊è¡ãã¥ãŒã«ãããŠã¯ç«¶åããªãæäœã®ã³ã¹ãã競åããæäœã®ã³ã¹ããèŠçŽ ã®é åºä¿èšŒããã¬ãŒããªãã«ããå¿ èŠããããããã«ãã£ãŠæ¢åã®ãã¥ãŒãããã»ãã³ãã£ã¯ã¹ã匱ããªããŸãã
ãã®ãããªå¯Ÿç«è»žã«ã¯ããšãã°
- åºå®é· vs å¯å€é·
- ããããã³ã° vs äžæžã
- ã·ã³ã°ã«ãšã³ã vs ãã«ããšã³ã
- å³å¯ãªFIFOã«ããé åº vs åªå 床ã«ããé åº
ãªã©ããããŸãã
ãã®ææ¡ã¯ä»ã®æããã®ãããªäžŠè¡ãã¥ãŒã®ã€ã³ã¿ãŒãã§ãŒã¹ã®ããŒã¹ãšãªãæŠå¿µçãªã€ã³ã¿ãŒãã§ãŒã¹ã®èŠä»¶ãå®çŸ©ããŠããŸãã
åºæ¬æäœ
䞊è¡ãã¥ãŒã€ã³ã°ã®åé¡ã«å¯Ÿããæ¬è³ªçãªè§£æ±ºçã¯ãåç §ããŒã¹ã§ã¯ãªãå€ããŒã¹ã®æäœãžç§»è¡ããããšã§ãããã®ããã«æ¬¡ã®2çš®é¡ã®åºæ¬æäœãå®çŸ©ããŠããŸã
// èŠçŽ ããã¥ãŒã€ã³ã°ãã
void queue::push(const Element&);
void queue::push(Element&&);
// èŠçŽ ããã¥ãŒããåãåºã
// èŠçŽ ã¯ã³ããŒã§ã¯ãªãã ãŒãããã
void queue::pop(Element&);
ããã§ã®queue
ã¯ç¹å®ã®ãã¥ãŒã瀺ããã®ã§ã¯ãªããã³ã³ã»ããçãªãã¬ãŒã¹ãã«ãã§ãã
ãããã®æäœã¯ãŸãããããã³ã°ã䌎ãæäœã§ãããããã¥ãŒãæºæ¯/空ã®å Žåã«åŸ æ©ããæäœã®ç«¶åãåé¿ããããã«ãããã¯ãããå¯èœæ§ããããŸãã
å³ææäœ
æºæ¯/空ã®ãã¥ãŒã§åŸ æ©ãããšæäœãå®äºãããŸã§ã«ãã°ããæéãèŠããå¯èœæ§ããããæ©äŒè²»çšãããããŸãããã®åŸ ã¡æéãåé¿ããããšã§ãæºæ¯/空ã®ãã¥ãŒã§æäœã®å®äºãåŸ æ©ãã代ããã«ä»ã®äœæ¥ãè¡ãããšãã§ããŸãããã®ããã«ã次ã®2çš®é¡ã®å³ææäœïŒåŸ æ©ããªãæäœïŒãå®çŸ©ããŠããŸã
// ãã¥ãŒãæºæ¯/ã¯ããŒãºç¶æ
ã®å Žåã¯ãã®ç¶æ
ãè¿ããããã§ã¯ãªãå Žåã«ãã¥ãŒã€ã³ã°ãqueue_op_status::successãè¿ã
queue_op_status queue::try_push(const Element&);
// ãã¥ãŒãæºæ¯/ã¯ããŒãºç¶æ
ã®å Žåã¯ãã®ç¶æ
ãè¿ãã第äžåŒæ°ã第äºåŒæ°ãžã ãŒããã
// ããã§ã¯ãªãå Žåã«ãã¥ãŒã€ã³ã°ãqueue_op_status::successãè¿ã
queue_op_status queue::try_push(Element&&, Element&);
// ãã¥ãŒã空ãªãqueue_op_status::emptyãè¿ã
// ããã§ã¯ãªãå Žåã«èŠçŽ ããã¥ãŒããåãåºãïŒã³ããŒã§ã¯ãªãã ãŒããããïŒãqueue_op_status::successãè¿ã
queue_op_status queue::try_pop(Element&);
queue_op_status
ã¯æ¬¡ã®ãããªã¹ã³ãŒãä»ãåæåã§ã
enum class queue_op_status {
success,
empty,
full,
closed
};
ãããã®æäœã¯ãã¥ãŒãæºæ¯/空ã®å Žåã«ãããã¯ããŸããããæäœã®ç«¶åãåé¿ããããã«ãããã¯ãããå¯èœæ§ããããŸãã
ãã¥ãŒã®ã¯ããŒãº
éä¿¡ã«ãã¥ãŒã䜿çšããŠããã¹ã¬ããã§ã¯ããã¥ãŒãäžèŠã«ãªã£ãå Žåã«ãã®ãã¥ãŒã䜿çšããŠããä»ã®ã¹ã¬ããã«ãã®ããšãéç¥ããã¡ã«ããºã ãå¿ èŠã«ãªãå ŽåããããŸããå žåçã«ã¯ãããã¯ãã¥ãŒãšã¯å¥ã®æ¡ä»¶å€æ°ãã¢ãããã¯å€æ°ãªã©ã®åž¯åå€ä¿¡å·ã䜿çšãããŸãããã ãããã®ã¢ãããŒãã§ã¯ããã®ãã¥ãŒã§åŸ æ©ããŠããä»ã®ã¹ã¬ãããèµ·åºããªããã°ãªããªãåé¡ãããããã®ããã«ãã¥ãŒã®æºæ¯/空ã®ããããã³ã°ã«äœ¿çšãããæ¡ä»¶å€æ°ã«ã¢ã¯ã»ã¹ããå¿ èŠãåºãŠãããªã©ãã€ã³ã¿ãŒãã§ãŒã¹ã®è€éããšå±éºæ§ãå¢å€§ãããŸãããŸãããã¥ãŒããã¯ã¹ãã¢ãããã¯å€æ°ã䜿çšããããšã§ããã©ãŒãã³ã¹ã«åœ±é¿ãåã¶å¯èœæ§ããããŸãã
ãã®ããããã®ææ¡ã§ã¯ãã®ãããªã·ã°ãã«ããã¥ãŒèªäœã§ãµããŒãããããšãéžæããŠãããããã«ãã£ãŠã³ãŒãã£ã³ã°ãããªãç°¡çŽ åãããŸãã
ãã®ã·ã°ãã«ã®ããã«ããã¥ãŒã¯ã¯ããŒãºïŒclose()
ïŒãè¡ãããšãã§ããŸããããã¹ã¬ããã§ãã¥ãŒãã¯ããŒãºããããšæ°ããèŠçŽ ããã®ãã¥ãŒã«æ¿å
¥ïŒpush
ïŒããããšãã§ããªããªããŸããã¯ããŒãºæžãã¥ãŒã«å¯Ÿããæ¿å
¥æäœã¯queue_op_status::closed
ãè¿ããäŸå€ãšããŠã¹ããŒããŸãããã¥ãŒã«ååšããèŠçŽ ã¯åãåºãïŒpop
ïŒãå¯èœã§ããããã¥ãŒã空ã§ã¯ããŒãºãããŠããå Žåãåãåºãæäœã¯queue_op_status::closed
ãè¿ããäŸå€ãšããŠã¹ããŒããŸãã
// ãã¥ãŒãéãã
void queue::close() noexcept;
// ãã¥ãŒãéããããŠããã°trueãè¿ã
bool queue::is_closed() const noexcept;
// ãã¥ãŒãéããããŠããã°queue_op_status::closedãè¿ã
// ããã§ãªããªãã°ãèŠçŽ ããã¥ãŒã€ã³ã°ãã
queue_op_status queue::wait_push(const Element&);
queue_op_status queue::wait_push(Element&&);
// ãã¥ãŒã空ã§éããããŠããã°queue_op_status::closedãè¿ã
// ããã§ã¯ãªãããã¥ãŒã空ãªãã°queue_op_status::emptyãè¿ã
// ãã以å€ã®å Žåããã¥ãŒããèŠçŽ ãåãåºãqueue_op_status::successãè¿ã
queue_op_status queue::wait_pop(Element&);
wait_
ãšããpush/pop
æäœã¯ããã¥ãŒãéããããŠããå Žåã«äŸå€ãåé¿ããããã®ã€ã³ã¿ãŒãã§ãŒã¹ã§ãããã®æäœã¯ãã¥ãŒãéããããŠãããæºæ¯/空ã®å Žåã«åŸ
æ©ããæäœã®ç«¶åãåé¿ããããã«ãããã¯ãããå¯èœæ§ããããŸãã
ã¯ããŒãºåŸã®ãã¥ãŒãåéããããŠãŒã¹ã±ãŒã¹ãããããã®ææ¡ã§ã¯ãã®ããã®ã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããŠããŸã
// ãã¥ãŒããªãŒãã³ãã
void queue::open();
ãã¥ãŒãåéããæ©èœãå°é£ã«ãªãå®è£
ã¯çŸåšææ¡ãããŠã¯ããŸããããååšããå¯èœæ§ããããŸãããŸãããã¥ãŒã®åéã¯éåžžãã¥ãŒãéããŠããŠç©ºã®å Žåã«ã®ã¿åŒã³åºãããšãã§ããããã«ãã£ãŠã¯ãªãŒã³ãªåæãã€ã³ããæäŸããããšãã§ããŸãããã ãã空ã§ãªããã¥ãŒã§open()
ãåŒã³åºãããšã¯å¯èœã§ãã
is_closed()
ãfalse
ãè¿ãå Žåã§ããä»ã®ã¹ã¬ããããã¥ãŒãåæã«ã¯ããŒãºããå¯èœæ§ããããããåŸç¶ã®æäœã§ãã¥ãŒãéããããŠããä¿èšŒã¯ãããŸããã
ãªãŒãã³æäœãå©çšã§ããªãå Žåããã¥ãŒãéãããããšãã¥ãŒã¯éãããŸãŸã«ãªããšããä¿èšŒããããŸãããããã£ãŠãã®å Žåãããã°ã©ããä»ã®ãã¹ãŠã®ã¹ã¬ããããã¥ãŒãéããªãããã«çŽ°å¿ã®æ³šæãæããªãéãã¯ãis_closed()
ã®æ»ãå€ã¯true
ã®ã¿ãæå³ãæã¡ãŸãã
ãã¥ãŒã®åéã«ã¯ãããã®åé¡ãããããããã®ææ¡ã§ã¯ãã®ã€ã³ã¿ãŒãã§ãŒã¹ãæ瀺ããã«ãšã©ãææ¡ããŠããŸããã
èŠçŽ åã®èŠä»¶
äžèšã®æäœã®ããã«ã¯ãèŠçŽ åã«ã¯ã³ããŒ/ã ãŒãã³ã³ã¹ãã©ã¯ã¿ãã³ããŒ/ã ãŒãä»£å ¥æŒç®åãåã³ãã¹ãã©ã¯ã¿ãå¿ èŠã«ãªããŸãã
ã³ã³ã¹ãã©ã¯ã¿ãšä»£å ¥æŒç®åã¯äŸå€ãæããå¯èœæ§ããããŸãããåŸç¶ã®æäœã®ããã«ã¯ãªããžã§ã¯ããæå¹ãªç¶æ ã®ãŸãŸã«ããŠããå¿ èŠããããŸãã
äŸå€ãã³ããªã³ã°
åºæ¬æäœã®2ã€ã®æäœïŒpush()/pop()
ïŒã¯ãã¥ãŒã®ç¶æ
ã«ãã£ãŠäŸå€ãæããå¯èœæ§ããããŸãããã®äŸå€ãªããžã§ã¯ãã¯std::exception
ã®æŽŸçã¯ã©ã¹ã§ãããqueue_op_state
ã®å€ãå«ãã§ããå¿
èŠããããŸãã
ä»ã®ã¹ã¬ããããã¥ãŒã®ç¶æ ãç£èŠããŠããæã«å€æŽãééçã«å ã«æ»ãããšãã§ããªãããã䞊è¡ãã¥ãŒã¯èŠçŽ åãã¹ããŒããäŸå€ã®åœ±é¿ãå®å šã«é ãããšã¯ã§ããŸããããã®ãããªäŸå€ã¯èŠçŽ åã®ã³ããŒ/ã ãŒãã³ã³ã¹ãã©ã¯ã¿åã³ã³ããŒ/ã ãŒãä»£å ¥æŒç®åããæããããå¯èœæ§ããããŸãã
ãã以å€ã®å Žåããã¥ãŒã¯ãã¡ã¢ãªç¢ºä¿ããã¥ãŒããã¯ã¹ãæ¡ä»¶å€æ°ããäŸå€ãåã¹ããŒããå¯èœæ§ããããŸãã
èŠçŽ ã®ã³ããŒ/ã ãŒããäŸå€ãæããå¯èœæ§ãããå Žåãäžéšã®ãã¥ãŒæäœã«ã¯è¿œå ã®åäœãå®çŸ©ãããŠããŸã
- æ§ç¯æã¯äŸå€ãåã¹ããŒããæ§ç¯ããããšããŠããèŠçŽ ãç Žæ£ãã
- æ¿å ¥æäœã¯åã¹ããŒãããã¥ãŒã®ç¶æ ã¯å€åããªã
- åãåºãæäœã¯åã¹ããŒããåãåºãããšããŠããèŠçŽ ã¯ãã¥ãŒããåãé€ãããïŒèŠçŽ ã¯å®è³ªçã«å€±ãããïŒ
ãã®ææ¡ã§ã¯ãããã®èŠä»¶ã«æ²¿ã£ãå
·äœçãªãã¥ãŒãææ¡ããŠã¯ããŸããããP1958R0ã§ãã®äžã€ã§ããbuffer_queue
ãææ¡ãããŠããä»ãgoogle-concurrency-libraryã«ãã®ææ¡ã®åæã®ã€ã³ã¿ãŒãã§ãŒã¹ãããŒã¹ãšããå®è£
ããããŸãã
ãã®ææ¡ã¯ããã£ãŒãããã¯ãåŸãããã«Concurrency TS v2å ¥ããç®æããŠããŸãã
<chrono>
ã®æèšåã®now()
ãæé©åã«ãã£ãŠäžŠã¹æ¿ããããªãããã«ããææ¡ã
<chrono>
ã®æèšåïŒsteady_clock
ãªã©ïŒã¯ãã®éçã¡ã³ãé¢æ°now()
ã«ãã£ãŠãã®æèšã®ç€ºãçŸåšã®æå»ïŒcurrent point in timeïŒãååŸããããšãã§ããŸãããããããã®çŸåšã®æå»ãäœãæãã®ãäžæçã§ãããå¿
ãããã³ãŒãã«èšè¿°ããå®è¡å°ç¹ã§ã®çŸåšæå»ãååŸããªãããšããããŸãã
ææ¡ããããµã³ãã«ã³ãŒã
#include <chrono>
#include <atomic>
#include <iostream>
std::size_t fib(std::size_t n) {
if (n == 0)
return n;
if (n == 1)
return 1;
return fib(n - 1) + fib(n - 2);
}
int const which{42};
int main() {
// fib()ã®å®è¡ã«ãããæéãèšæž¬ãã
auto start = std::chrono::high_resolution_clock::now(); // #1
auto result = fib(which); // #2
auto end = std::chrono::high_resolution_clock::now(); // #3
std::cout << "fib(" << which << ") is " << result << std::endl;
std::cout << "Elapsed time is "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
<< "ms" << endl;
return 0;
}
ãã®ãããªã³ãŒãã¯ããªãåºæ¬çãªãã®ã§ãããå°ãªããšãMSVCã¯æé©åãæå¹ã«ãããš#2 #3
ã®é çªãå
¥ãæ¿ããŠã#1 -> #3 -> #2
ã®ããã«å®è¡ããŠããŸããçµæ0msãåºåãããŸãããã®ãããªæé©åã¯æšæºã®ç¯å²å
ã§èš±å¯ãããŠããããããã®æé©åèªäœã¯åæ³ã§ãã
ããã¯ã·ã³ã°ã«ã¹ã¬ããããã°ã©ã ã«ãããå®è¡é åºã®äžŠã¹æ¿ãã§ãããããæšæºã®ç¯å²å ã§åé¿ããã®ã¯é£ããããã§ãããã¡ã€ã«ãåå²ããããšã§åé¿ã§ããããã§ããããããããã°ã©ã å šäœã®æé©åããªã³ã¯ææé©åãèæ ®ãããšç¢ºå®ãªãã®ãšã¯èšããŸããããŸãããã®åé¡ã¯ã³ã³ãã€ã©ã«ãã£ãŠã¯èµ·ãããªãããããããåé¿çãå«ãããã®ãããªã³ãŒãã®ç§»æ€æ§ãæããŠããŸãã
ããã°ã©ã äžã§çŸåšã®ã¿ã€ã ã¹ã¿ã³ããååŸãããšããåçŽãªåŠçã«ãããã®ãããªçœ ãæœãã§ããŠåé¿ãé£ãããšããã®ã¯å€§ããªåé¡ã§ããããã®ææ¡ã¯ãã®æ¹åã®ããã®ãã®ã§ãã
ãã®ææ¡ã§ã¯ãã®åé¡ã®è§£æ±ºã®ããã«ããã€ãã®æ¹æ³ãæããŠããŸã
- æšæºãå€æŽã¯ããªãããã¬ã€ãã³ã¹ãå
å®ããã
- SG20ã§é åžå¯èœãªã¬ã€ãã³ã¹ãäœæããã ãã§ãæè²è ã«ã¯å€§ããªå©ãã«ãªã
- ç·šéäžã®å€æŽãå ãã
- âã®ã¬ã€ãã³ã¹ãæšæºã«èšè¿°ãã
now()
ã®äžŠã¹æ¿ããçŠæ¢ãã- ãã®ã¢ãããŒãã¯R0ã®è°è«ã«ãããŠå®è£ å¯èœæ§ã«ã€ããŠæžå¿µããã£ã
- ã·ã³ã°ã«ã¹ã¬ãããã§ã³ã¹ãå°å
¥ãã
- ãã®åé¡ãçºçããã®ã¯æå»ååŸã«æ¢ãŸããªããšèããããããããã®ãŠãŒã¹ã±ãŒã¹ã«å¿ããããã«ããäžè¬çãªãœãªã¥ãŒã·ã§ã³ãæäŸãã
- ãã®ã¢ãããŒãã¯R0ã§ææ¡ããŠãããã®ã ã£ãããå®è£ å¯èœæ§ã«ã€ããŠæžå¿µããã£ã
ãã ããçŸåšã®ãšããã©ãããéžæããŠã¯ããŸããã
ãã®ææ¡ã®R0ã§ã¯ãã®åé¡ã®è§£æ±ºã®ããã®ã·ã³ã°ã«ã¹ã¬ãããã§ã³ã¹ãææ¡ããŠããŸãããã2016幎ã«ã¬ãã¥ãŒãããéã«ã¯ãã®å®è£ å¯èœæ§ã®æžå¿µãªã©ããåãå ¥ãããããææ¡ã®è¿œæ±ã¯ã¹ãããããŠããŸããããããã2022幎ã®KonaäŒè°ã«ãããSG1ã®ããŒãã£ã³ã°äžã«ãã®åé¡ãåãäžãããããã®ææ¡ã®æ¹èšçãæãŸããããšã§ããšããããåé¡ãæŽçããR1ïŒãã®ãªããžã§ã³ïŒãå床æåºãããŸããã
èè ã®æ¹ãSG1ã®ã¡ã³ãã¯ãçŸåšã®æå»ã®ååŸãšããåçŽãªã¿ã¹ã¯ã§ããã°ã©ããçŽé¢ãããã®åé¡ã¯ãçŸç¶ã®æ¹åãããåºãæ€èšããã®ã«ååã«æ·±å»ã ãšèããŠããããã§ãã
Callableãææããªãstd::function
ã§ããstd::function_ref
ã®ææ¡ã
以åã®èšäºãåç §
- P0792R6 function_ref: a non-owning reference to a Callable - C++WG21æ次ææ¡ææžãçºããïŒ2022幎01æïŒ
- P0792R8 function_ref: a non-owning reference to a Callable - C++WG21æ次ææ¡ææžãçºããïŒ2022幎02æïŒ
- P0792R9 function_ref: a non-owning reference to a Callable - C++WG21æ次ææ¡ææžãçºããïŒ2022幎05æïŒ
- P0792R10 function_ref: a non-owning reference to a Callable - C++WG21æ次ææ¡ææžãçºããïŒ2022幎06æïŒ
- P0792R11 function_ref: a non-owning reference to a Callable - C++WG21æ次ææ¡ææžãçºããïŒ2022幎09æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãLWGã®ãã£ãŒãããã¯ã«ããæèšã®èª¿æŽãšãã¡ã³ãå€æ°ãã€ã³ã¿ã誀ã£ãŠåŠçããŠããæšè«è£å©ã®ä¿®æ£ã§ãã
ãã®ææ¡ã¯æ¬¡ã®ãªããžã§ã³ïŒæªå ¬éïŒãLWGã®ã¬ãã¥ãŒããã¹ããŠã次ã®å šäœäŒè°ã«ãããããããšã決ãŸã£ãŠããŸãïŒC++26ã¿ãŒã²ããã§ãïŒã
<cmath>
ãš<complex>
ã®æ°åŠé¢æ°ãconstexpr
ã«ããææ¡ã
<cmath>
ã®æ°åŠé¢æ°ãã¯ãããšããæµ®åå°æ°ç¹æ°ãæ±ããã®ãconstexpr
察å¿ãããã«ããã£ãŠåé¡ãšãªã£ãŠããã®ã¯ãåãæµ®åå°æ°ç¹æ°å€ã«å¯Ÿããããé¢æ°ã®çµæãã³ã³ãã€ã©ã®èšå®ããã©ãããã©ãŒã ãå®è¡ã¿ã€ãã³ã°çã®ã³ã³ããã¹ãã«ãã£ãŠçããå¿
èŠãããã®ãïŒãšããç¹ã§ããæããã«ãããªã£ãŠæ¬²ããã®ã§ãããæµ®åå°æ°ç¹æ°ã®ç¹æ§ãªã©ã®äºæ
ã«ãã£ãŠããã¯å®éã«ã¯å°é£ã§ããããããããšãããé¢æ°ã®å®è¡çµæã«ã€ããŠã©ã®ããã«èŠå®ããã®ãããããã¯ã©ã®ãããªä¿èšŒãäžããã®ãïŒãåé¡ãšãªããŸãã
C++23ã«ãããP0533R9ã«ãã<cmath>
çã®é¢æ°ã®constexpr
察å¿ã«ããã£ãŠããã®ãããªåé¡ã®è°è«ãåé¿ããããã«ãååæŒç®ïŒ+ - * /
ïŒãããïŒãã®äºæ
ã®äžã§ã¯ïŒè€éã§ãªããšã¿ãªãããé¢æ°ã®ã¿ãconstexpr
察å¿ãããŸããã
ãã®ææ¡ã¯æ¬¡ã®ãããªèšèšæéã«ãã£ãŠã<cmath>
ãš<complex>
ã«ããã»ãŒãã¹ãŠã®æ°åŠé¢æ°ãconstexpr
察å¿ãããããšããŠããŸã
- æ°åŠé¢æ°ã®å®è¡çµæãå®è¡æãšã³ã³ãã€ã«æã§ç°ãªãããšã蚱容ãã
- æ°åŠé¢æ°ã®å®æ°å®è¡ãç°ãªããã©ãããã©ãŒã ã§ç°ãªãããšã蚱容ãã
<cmath>
å ã®æ¢åé¢æ°ã«æ£ç¢ºãªåäœã矩åä»ããã®ã§ã¯ãªããQoIã®å®éåã奚å±ããããšãæãŸãã
ããããå®è¡æã«ãããçŸåšã®<cmath>
ã®æ°åŠé¢æ°ãæµ®åå°æ°ç¹æŒç®ã¯ãç°ãªãã³ã³ãã€ã©ããã©ãããã©ãŒã ã®éããããã¯ç°ãªãã³ã³ãã€ã©ãªãã·ã§ã³ïŒ-ffast-math
ãªã©ïŒã®éã§çµæãäžèŽããªãããšã¯é·ãé蚱容ãããŠããŸãããŸããå®æ°åŒã§ã¯æ°åŠé¢æ°ãåŒã³åºããªãæµ®åå°æ°ç¹æŒç®ã¯å¯èœã§ãããèŠæ Œãå©çšè
ããã®çµæã®å®è¡æãšã³ã³ãã€ã«æã®å·®ç°ã蚱容ããŠããŸãïŒå®è¡æã«ãããäžžãã¢ãŒãã®å€æŽãFMAã®å©çšãªã©ïŒã
costexpr
ãªæ°åŠé¢æ°ã«ã®ã¿éå°ãªæ£ç¢ºæ§ãçµæã®äžè²«æ§ãèŠæ±ããããšã¯ãå®è£
ã®å°é£ããé«ãããšãšãã«ãããã®ãã®ãå®è¡æãšã³ã³ãã€ã«æã®åºåå·®ã®åå ãšãªããŸãããã®ãããã®ææ¡ã§ã¯ã蚱容ãããŠããçŸåšã®å®è¡æã®æ¯ãèããããŒã¹ãšããèšèšæéã«ãã£ãŠæ°åŠé¢æ°ãconstexpr
察å¿ãããæ¹éãæŒããŠããŸãã
æšæºã©ã€ãã©ãªã«ãBLASãããŒã¹ãšããå¯è¡åã®ããã®ç·åœ¢ä»£æ°ã©ã€ãã©ãªãè¿œå ããææ¡ã
以åã®èšäºãåç §
- P1673R3 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2021幎04æïŒ
- P1673R4 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2021幎08æïŒ
- P1673R5 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2021幎10æïŒ
- P1673R6 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2021幎12æïŒ
- P1673R7 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2022幎04æïŒ
- P1673R8 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2022幎05æïŒ
- P1673R9 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2022幎06æïŒ
- P1673R10 A free function linear algebra interface based on the BLAS - C++WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
in_{vector,matrix,object}*_t
ããŠããŒã¯ãªã¬ã€ã¢ãŠããæã€ãšããèŠä»¶ãåé€in_{vector,matrix,object}*_t
ã«å¯Ÿããååä»ãèŠä»¶ã説æå°çšã³ã³ã»ããã«å€æŽ- 察称ãªHermitian updateã¢ã«ãŽãªãºã ãå¶çŽããããã«ã説æå°çšã³ã³ã»ãã
possibly-packed-inout-matrix
ãè¿œå - æ°ãã説æå°çšã³ã³ã»ãããšéè€ããå¶çŽãåé€
- å
šãŠã®ã¢ã«ãŽãªãºã ã®å¶çŽããã
mdspan
ããŠããŒã¯ãªã¬ã€ã¢ãŠããæã€ãšããå¶çŽãåé€ - ãã¯ãã«/è¡åãªããžã§ã¯ãã®ãã³ãã¬ãŒããã©ã¡ãŒã¿ã
mdspan
ãžã®const
巊蟺å€åç §ãããã¯éconst
å³èŸºå€åç §ãæšè«ããå¯èœæ§ããããšããèŠä»¶ãåé€ - äž¡æ¹ã®ãã¯ã¿åãå«ããããã«
dot
ã®èŠä»¶ãä¿®æ£ mdspan
ã®element_type
ãšã€ãªã¢ã¹ã®ä»£ããã«value_type
ãšã€ãªã¢ã¹ã䜿çšããããã«ãããã€ãã®é¢æ°ã®èŠå®ãä¿®æ£matrix_vector_product
ã®ãã³ãã¬ãŒããã©ã¡ãŒã¿é åºãšä»®åŒæ°ã®é åºãåããã- LEWGã®ã¬ã€ãã³ã¹ã«åŸã£ãŠãå¹æãšå¶çŽãæ°åŠçã«èšè¿°ããããã«ãã
matrix_one_norm
ã®äºåæ¡ä»¶ïŒèŠçŽ ã®abs()
ã®çµæãT
ã«å€æå¯èœã§ããããšïŒãå¶çŽã«å€æŽvector_abs_sum
ã®äºåæ¡ä»¶ïŒinit + abs(v[i])
ã®çµæãT
ã«å€æå¯èœã§ããããšïŒãå¶çŽã«å€æŽ- Bikeshedã®ä»£ããã«Pandocã䜿çšããããã«ãã
conjugated-scalar
ã®conjugatable<ReferenceValue>
ãé©æ ŒèŠä»¶ã§ã¯ãªãå¶çŽã«å€æŽ- âIf an algorithm in [linalg.algs] accesses the elements of an out-vector, out-matrix, or out-object, it will do so in write-only fashion.âãšããæèšãåé€
- P2642ã®å 容ãR2ã«ã¢ããããŒã
- å
šãŠã®ã¿ã°åã®
default
å®è£ ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã«explicit
ãä»å givens_rotation_setup
ãåºåãã©ã¡ãŒã¿ã§ã¯ãªãæ°ããgivens_rotation_setup_result
æ§é äœã®å€ãè¿ãããã«å€æŽ
ãªã©ã§ãã
å€æ¬¡å
é
åã¯ã©ã¹mdarray
ã®ææ¡ã
- P1684R1 mdarray: An Owning Multidimensional Array Analog of mdspan - C++WG21æ次ææ¡ææžãçºããïŒ2022幎03æïŒ
- P1684R2 mdarray: An Owning Multidimensional Array Analog of mdspan - C++WG21æ次ææ¡ææžãçºããïŒ2022幎04æïŒ
- P1684R3 mdarray: An Owning Multidimensional Array Analog of mdspan - C++WG21æ次ææ¡ææžãçºããïŒ2022幎07æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãsize constructible containerèŠä»¶ãåé€ããé¢é£ããã³ã³ã¹ãã©ã¯ã¿ã§ã¯äºåæ¡ä»¶ã䜿çšããããã«ããããšã§ãã
ãã¡ã€ã«I/Oã©ã€ãã©ãªã®ææ¡ã
ãã®ææ¡ã®ãã¡ã€ã«I/Oã©ã€ãã©ãªã¯llfioãšããã©ã€ãã©ãªãããŒã¹ãšãããã®ã§ãllfioã¯çŸä»£ã®é«æ§èœã¹ãã¬ãŒãžã«å¯ŸããI/Oã§çè«æ§èœå€ã«è¿«ãããã©ãŒãã³ã¹ãåŒãåºãããšãã§ããããšã謳ã£ãŠããŸãããŸããllfioã¯POSIXïŒLinux/MacçïŒãšWindowsã«ãããI/Oãæœè±¡åããŠæ±ãã¯ãã¹ãã©ãããã©ãŒã ãªã©ã€ãã©ãªã§ããããŸãã
ãã®ææ¡ã§ã¯ããã®llfioããfile_handle
ãšmapped_file_handle
ãäžå¿ãšãããã¡ã€ã«æ¯ã®I/Oæ©èœãæšæºã©ã€ãã©ãªãžå°å
¥ããããšããŠããŸãïŒllfioèªäœã¯ãããã¯ãŒã¯I/Oããã¡ã€ã«ã·ã¹ãã æäœãªã©ããåºãæ©èœãæã£ãŠããŸãïŒã
llfioã§ã¯ãã¡ã€ã«ããã¡ã€ã«ã·ã¹ãã ã®èŠçŽ ãªã©ããã³ãã«ãšãã次ã®ãããª7éå±€ã®éå±€æ§é ã«ãã£ãŠæœè±¡åããŠããŸã
handle
- ãªãŒãã³/ã¯ããŒãºããã¹ã®ååŸãã¯ããŒã³ãè¿œå ã®ã¿ã®set/unsetããã£ãã·ã¥ã®å€æŽããªã©ã®ç¹æ§ãæäŸãã
fs_handle
- inodeçªå·ãæã€
handle
- inodeçªå·ãæã€
path_handle
- ãã¡ã€ã«ã·ã¹ãã ã®äžéšåãžã®ç«¶åã®ç¡ãã¢ã³ã«ãŒ
directory_handle
- ãã¡ã€ã«ã·ã¹ãã ãåæãã
io_handle
- åæã¹ãã£ãã¿/ã®ã£ã¶ãŒI/Oããã€ãç¯å²ããã¯ãæäŸãã
file_handle
- ãã¡ã€ã«ã®ãªãŒãã³/ã¯ããŒãºãæ倧ãµã€ãºã®èšå®/ååŸãæäŸãã
mapped_file_handle
- ã¡ã¢ãªãããããããã¡ã€ã«ã«å¯Ÿããäœã¬ã€ã³ãã³ã·ã®ã¹ãã£ãã¿/ã®ã£ã¶ãŒI/OãæäŸãã
ãã®éå±€æ§é ã¯ãã®ãŸãŸã¯ã©ã¹ã®ç¶æ¿é¢ä¿ã«å¯Ÿå¿ããŠããŸãã
file_handle
ãšmapped_file_handle
ã¯6,7éå±€ã«äœçœ®ãããã®ã§ããã¡ã€ã«ãšãã察象ã«å¯Ÿããå®éã®I/OæäœãæäŸããŸãã䞻圹ããã®2ã€ã§ããã ãã§ãäžã®5éå±€ã®ã¯ã©ã¹ãäžç·ã«å°å
¥ãããŸãã
ææ¡ææžãããã¹ãã£ãã¿æžã蟌ã¿ã®ãµã³ãã«ã³ãŒã
// äžèšéå±€æ§é ã«ãã£ãŠãfile_handleã§ãmapped_file_handleã§ã䜿çšå¯èœ
void write_and_close(file_handle &&fh) {
// ãã¡ã€ã«ã®æ倧ãµã€ãºãèšå®
// mapped_file_handleã¯ãã¡ã€ã«ãµã€ãºãåºå®ã®ããã«å¿
èŠ
fh.truncate(12).value();
// æžã蟌ãããŒã¿ã®ãããã¡
const char a[] = "hel";
const char b[] = "l";
const char c[] = "lo w";
const char d[] = "orld";
// ã®ã£ã¶ãŒæžã蟌ã¿ïŒãã©ãã©ã®ãããã¡ããã®ã¹ãã£ãã¿æžã蟌ã¿ïŒãè¡ã
// file_handleã®å Žå : max_buffers() >= 4ãªãã°ãã®æžã蟌ã¿ã¯äžŠè¡ããèªã¿åãã«å¯ŸããŠã¢ãããã¯
// ãã®ãããªèªã¿åãã¯äœãèªãŸãªãããå®äºããçµæãèªããã®ã©ã¡ããïŒç Žæã¯ãªãïŒ
// mapped_file_handleã®å Žå : æžã蟌ã¿ã«äŒŽãåæã¯è¡ããããèªã¿æžãã¯äžŠè¡ãããªãŒã/ã©ã€ã¿ãŒã«å¯ŸããŠç«¶åãããããè¿œå ã®åæãå¿
èŠã«ãªã
fh.write(
// ã®ã£ã¶ãŒãªã¹ãã®æå®
{ // å
¥åã¯std::byteã§è¡ããããããã£ã¹ããå¿
èŠ
{ reinterpret_cast<const byte*>(a), sizeof(a) - 1 },
{ reinterpret_cast<const byte*>(b), sizeof(b) - 1 },
{ reinterpret_cast<const byte*>(c), sizeof(c) - 1 },
{ reinterpret_cast<const byte*>(d), sizeof(d) - 1 },
}
// ããã©ã«ãã®ã¿ã€ã ã¢ãŠãã¯ç¡é
).value(); // 倱æããå Žåãfilesystem_erroräŸå€ãã¹ããŒãã
// ãã¡ã€ã«ã®ã¯ããŒãºã«å€±æããå Žåã«åããŠãæ瀺çã«ãã¡ã€ã«ãã¯ããŒãºãã
fh.close().value();
}
// æžã蟌ã¿çšã«ãã¡ã€ã«ããªãŒãã³
// å¿
èŠã«å¿ããŠãã¡ã€ã«ãäœæããã£ãã·ã¥ãã¹ã«ãŒããŠæžã蟌ã¿
write_and_close(file(
{}, // åèŠçŽ ïŒâïŒãæ¢çŽ¢ããããŒã¹ãã£ã¬ã¯ããªã®path_handleïŒãã®å Žåã¯ã«ã¬ã³ããã£ã¬ã¯ããªãæå³ããïŒ
"hello", // ããŒã¹ãã£ã¬ã¯ããªïŒâïŒããã®çžå¯Ÿçãªãã¹ãã©ã°ã¡ã³ããžã®path_viewïŒãã¡ã€ã«åïŒ
file_handle::mode::write, // æžã蟌ã¿ã¢ã¯ã»ã¹ãèŠæ±
file_handle::creation::if_needed, // å¿
èŠãªããã¡ã€ã«ãæ°èŠäœæ
file_handle::caching::reads_and_metadata // ã¹ãã¬ãŒãžã«å°éãããŸã§æžã蟌ã¿ïŒããã©ã«ãã¯none
).value()); // 倱æããå Žåãfilesystem_erroräŸå€ãã¹ããŒãã
const path_handle& somewhere;
// ã¡ã¢ãªãããã䜿çšããŠæ¢åãã¡ã€ã«ãæŽæ°ããäŸ
write_and_close(mapped_file(
somewhere, // åèŠçŽ ïŒâïŒãæ¢çŽ¢ããããŒã¹ãã£ã¬ã¯ããªã®path_handle
"hello2", // ããŒã¹ãã£ã¬ã¯ããªïŒâïŒããã®çžå¯Ÿçãªãã¹ãã©ã°ã¡ã³ããžã®path_viewïŒãã¡ã€ã«åïŒ
file_handle::mode::write, // æžã蟌ã¿ã¢ã¯ã»ã¹ãèŠæ±
file_handle::creation::open_existing // æ¢åãã¡ã€ã«ãéãã®ã¿ããã¡ã€ã«ããªãå Žåã«å€±æãã
// ããã©ã«ãã¯å
šãŠãã£ãã·ã¥ã䜿çšãã
).value()); // 倱æããå Žåãfilesystem_erroräŸå€ãã¹ããŒãã
mapped_file_handle
ã¯ã¡ã¢ãªã«ãããããããã¡ã€ã«ã®æœè±¡ã§ããããã¡ã€ã«æžã蟌ã¿ã«äŒŽã£ãŠãã¡ã€ã«ãµã€ãºã®èªå延é·ãè¡ãããªããªã©ã®å¶çŽããããŸããäžæ¹ã§ãfile_handle
ã¯ãã£ãšåºããã¡ã€ã«ã®æœè±¡ã§ãããéåžžãã¡ã€ã«ã®èªå延é·æ©èœãæã¡ãŸãã
åI/Oæäœããã³ãã«äœæã®çµæã§value()
ãåŒãã§ããã®ã¯ãããããã®æäœãresult<T>
åãè¿ããŠããããã®æåçµæãååŸããããã§ããresult<T>
ã¯ãšã©ãŒåãstd::error
ïŒP1028R4ïŒã«åºå®ãããstd::expected
ã®ãããªåã§ãåããããªã€ã³ã¿ãŒãã§ãŒã¹ãæã£ãŠããŸãã
file_handle
ãšmapped_file_handle
ã®file
ãšã¯UNIXã«ããããã¡ã€ã«ãšããæŠå¿µã®ãããªãã®ã§ãå¿
ããããã¡ã€ã«ã·ã¹ãã äžã®ãã¡ã€ã«ã ããæå³ããã®ã§ã¯ãªãããã¡ã€ã«ãšããŠæ±ãããã®å
šäœãæããŠããŸããäŸãã°ãASIOããœã±ããããŒã¹ã®I/Oã©ã€ãã©ãªã§ãããšãããšããã®ã©ã€ãã©ãªã¯ãã¡ã€ã«ããŒã¹ã®I/Oã©ã€ãã©ãªã§ãã
ãã®ã©ã€ãã©ãªã¯æ¬¡ã®ãããªèšèšååã謳ã£ãŠããŸã
- ããã©ã«ããã©ã¡ãŒã¿ãèšå®ã¯ããã©ãŒãã³ã¹ãããã»ãã¥ãªãã£ãéèŠããã
- ããã¯ãã€ã§ãæ瀺çã«ãªããã¢ãŠãã§ãã
- å®è¡ãããI/Oã®çš®å¥ã«é¢ä¿ãªããåºç€ãšãªãã·ã¹ãã ã³ãŒã«ã®ã©ã€ã³ã¿ã€ã ãªãŒããŒããããè¶ ããïŒã©ã€ãã©ãªã®ïŒçµ±èšçã«èšæž¬å¯èœãªã©ã€ã³ã¿ã€ã ãªãŒããŒãããã¯ãªã
- ãã¹ãOSã®äžŠè¡I/Oã«é¢ããä¿èšŒãå¯èœãªéããã®ãŸãŸæäŸãã
- POSIXã®race free filesystem path lookupæ¡åŒµãäžå¿ãšããŠèšèšãããŠãã
- ã·ã¹ãã å ã§ã®ã©ãã§ããC++I/Oãšæçµã¹ãã¬ãŒãžããã€ã¹ã®éã®å šãŠã®ã¡ã¢ãªã³ããŒãåžžã«åé¿å¯èœã§ããå¿ èŠããã
- ã«ãŒãã«I/Oãã£ãã·ã¥å¶åŸ¡ããã³ä»®æ³ã¡ã¢ãªå¶åŸ¡æ©èœãæäŸãã
- ãã¡ã€ã«ã·ã¹ãã ã®ç«¶åãæ€ç¥ããŠåé¿ããæ©èœãæäŸããå°ãªããšããã¹ãOSãèš±å¯ããç¯å²ã§ç¬¬äžè ã«ãããã¡ã€ã«ã·ã¹ãã åæå€æŽã«ãã£ãŠå°å ¥ããã競åãå®å šã«ãªãã³ãŒããèšè¿°å¯èœã«ãã
çè
ã®æ¹ïŒllfioéçºè
ã®æ¹ïŒã«ããã°ãllfioã®äžã§file_handle
ãšmapped_file_handle
åšãã®APIããã³ABIã¯2020幎ããããå®å®ããŠãããåžå ŽååŒã®ããŒã¿åŠçã«ãããŠæ°å¹Žéã®äœ¿çšå®çžŸããããçŸåšã1TB/æ¥ã®ããŒã¿ãåŠçããŠããããšã®ããšã§ãã
ãã®ææ¡ã¯çŸåšã®ãšããæ©èœãèšèšã«ã€ããŠã®ã¬ãã¥ãŒãåããŠãã段éã§ãããå ·äœçãªæèšã¯ãããŸããã
- ned14/llfio P1031 low level file i/o and filesystem library for the C++ standard
- LLFIO: Mainpage
- P1883 é²è¡ç¶æ³
std::simd<T>
ãParallelism TS v2ããæšæºã©ã€ãã©ãªãžç§»ãææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- æµ®åå°æ°ç¹æ°ã©ã³ã¯ã«å¯Ÿå¿ããã³ã³ã¹ãã©ã¯ã¿ã®
explicit
æå®ã®è¿œå - æ°ããABIã¿ã°ã®åããããã¯ç°ãªãã»ãã³ãã£ã¯ã¹ã«ã€ããŠè¿œèš
- ã»ã¯ã·ã§ã³4å°å ¥æ®µèœãä¿®æ£
simd::size
ãstd::integral_constant<size_t, N>
åã®static constexpr
å€æ°ã«å€æŽ- APIã®
constexpr
察å¿ã«ã€ããŠããã¥ã¡ã³ããè¿œèš constexpr
ãææ¡ããæèšã«è¿œå- ABIå¢çãè¶ããŠ
std::simd
ãããåãããããã®ABIã¿ã°ãåé€ - ãã£ã¹ãã€ã³ã¿ãŒãã§ãŒã¹ã®å€æŽãé©çš
ãªã©ã§ãã
ã³ã³ãã€ã«æïŒããªããã»ã¹æïŒã«ãã€ããªããŒã¿ãã€ã³ã¯ã«ãŒãããããã®ããªããã»ãã·ã³ã°ãã£ã¬ã¯ãã£ã#embed
ã®ææ¡ã
以åã®èšäºãåç §
- P1967R3
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2021幎04æïŒ - P1967R4
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2021幎06æïŒ - P1967R5
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2021幎04æïŒ - P1967R6
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2022幎05æïŒ - P1967R7
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2022幎06æïŒ - P1967R8
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2022幎07æïŒ - P1967R9
#embed
- a simple, scannable preprocessor-based resource acquisition method - C++WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ããã¡ã€ã«ã空ã§ããããšãæ€ç¥ããããã®__has_embed
ãšsuffix/prefix/if_empty
ã®æå®ããªãã·ã§ãã«ãªæ©èœããææ¡ããæ©èœã«ç§»åããããšãªã©ã§ãã
ããªãŒã¹ã¿ã³ãã£ã³ã°åŠçç³»ã«ãããŠã¯ããªãŒããŒããŒãå¯èœãªã°ããŒãã«::operator new
ãå¿
é ã§ã¯ãªããªãã·ã§ã³ã«ããããšããææ¡ã
以åã®èšäºãåç §
- P2013R1 : Freestanding Language: Optional
::operator new
- C++WG21æ次ææ¡ææžãçºããïŒ2020幎04æïŒ - P2013R3 : Freestanding Language: Optional
::operator new
- C++WG21æ次ææ¡ææžãçºããïŒ2020幎09æïŒ - P2013R3 : Freestanding Language: Optional
::operator new
- C++WG21æ次ææ¡ææžãçºããïŒ2021幎05æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãLWGã®ãã£ãŒãããã¯ãåæ ããããšã§ãã
ãã®ææ¡ã¯ãã§ã«LWGã®ã¬ãã¥ãŒãçµããŠããã次ã®å šäœäŒè°ã§æ祚ã«ãããããäºå®ã§ãã
Allocator Awareãªstd::optional
ã§ãããstd::pmr::optional
ãè¿œå ããææ¡ã
以åã®èšäºãåç §
- P2047R1 An allocator-aware optional type - C++WG21æ次ææ¡ææžãçºããïŒ2021幎02æïŒ
- P2047R2 An allocator-aware optional type - C++WG21æ次ææ¡ææžãçºããïŒ2021幎08æïŒ
- P2047R3 An allocator-aware optional type - C++WG21æ次ææ¡ææžãçºããïŒ2022幎07æïŒ
- P2047R4 An allocator-aware optional type - C++WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãææ¡ããæèšã®èª¿æŽãããã©ã«ãã®ã¢ãã±ãŒã¿åã®åŒæ°ã«std::remove_cv_t
ãéãããã«ããããšãmake_~
é¢æ°ã®åé€ïŒæèšããã¯æ¶ããŠãªãïŒïŒãªã©ã§ãã
ãã®ææ¡ã¯ã©ãããããã以äžè°è«ã«æéãè²»ãããªãããšã«ãªã£ãããã§ãã
<random>
ã«æ°ããç䌌乱æ°çæãšã³ãžã³ãè¿œå ããææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- Philoxã ãã«çç®ããAPIã®æèšãã·ã³ãã«ã«ãã
- ã«ãŠã³ã¿ããŒã¹ãšã³ãžã³ã®APIãæ¡åŒµãã
- Design considerationsãè¿œå
- ãšã³ãžã³åã«
set_counter()
ã¡ã³ãé¢æ°ãè¿œå counter_based_engine
ã®c
ãã³ãã¬ãŒããã©ã¡ãŒã¿ã®åé€
ãªã©ã§ãã
å
ã®ã·ãŒã±ã³ã¹ã®åèŠçŽ ã«ã€ã³ããã¯ã¹ãçŽä»ããèŠçŽ ãããªãæ°ããã·ãŒã±ã³ã¹ãäœæããRangeã¢ããã¿views::enumerate
ã®ææ¡ã
以åã®èšäºãåç §
- P2164R0 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2020幎5æïŒ
- P2164R1 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2020幎6æïŒ
- P2164R2 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2020幎9æïŒ
- P2164R3 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2020幎11æïŒ
- P2164R4 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2021幎02æïŒ
- P2164R5 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2021幎06æïŒ
- P2164R6 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2022幎08æïŒ
- P2164R7 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
- P2164R8 views::enumerate - C++WG21æ次ææ¡ææžãçºããïŒ2022幎11æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãææ¡ããæèšã®ä¿®æ£ã®ã¿ã§ãã
ãã®ææ¡ã¯2023幎2æã®IssaquahäŒè°ã§C++23ã«åããŠæ¡æãããŠããŸãã
宣èšä»¥é䜿çšãããè¿œå æ
å ±ãæäŸããããã®ååãã€ããå¿
èŠããªãå€æ°ãè¡šãããã«_
ãèšèªãµããŒãä»ãã§äœ¿çšã§ããæ§ã«ããææ¡ã
以åã®èšäºãåç §
- P2169R0 A Nice Placeholder With No Name - WG21æ次ææ¡ææžãçºããïŒ2020幎5æïŒ
- P2169R1 A Nice Placeholder With No Name - WG21æ次ææ¡ææžãçºããïŒ2022幎7æïŒ
- P2169R2 A Nice Placeholder With No Name - WG21æ次ææ¡ææžãçºããïŒ2022幎9æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãææ¡ããæèšãè¿œå ããããšãåå空éã¹ã³ãŒãã§ã¯è€æ°åã®äœ¿çšãçŠæ¢ããïŒä»¥åã¯ååä»ã¢ãžã¥ãŒã«æ¬æã®åå空éã¹ã³ãŒãã§ã®ã¿è€æ°å䜿çšå¯èœãšããŠããïŒããšãªã©ã§ãã
â
ããªãŒã¹ã¿ã³ãã£ã³ã°åŠçç³»ã§ã䜿çšå¯èœãªã©ã€ãã©ãªæ©èœã«ã€ããŠãæ©èœãã¹ããã¯ããè¿œå ããææ¡ã
以åã®èšäºãåç §
- P2198R0 Freestanding Feature-Test Macros and Implementation-Defined Extensions - C++WG21æ次ææ¡ææžãçºããïŒ2020幎07æïŒ
- P2198R1 Freestanding Feature-Test Macros and Implementation-Defined Extensions - C++WG21æ次ææ¡ææžãçºããïŒ2020幎10æïŒ
- P2198R2 Freestanding Feature-Test Macros and Implementation-Defined Extensions - C++WG21æ次ææ¡ææžãçºããïŒ2021幎07æïŒ
- P2198R3 Freestanding Feature-Test Macros and Implementation-Defined Extensions - C++WG21æ次ææ¡ææžãçºããïŒ2021幎11æïŒ
- P2198R4 Freestanding Feature-Test Macros and Implementation-Defined Extensions - C++WG21æ次ææ¡ææžãçºããïŒ2021幎12æïŒ
- P2198R5 Freestanding Feature-Test Macros and Implementation-Defined Extensions - C++WG21æ次ææ¡ææžãçºããïŒ2022幎04æïŒ
R6ã§ã®å€æŽã¯ã
- ææ°ã®ã¯ãŒãã³ã°ãã©ãããžã®è¿œé
- 次ã®C++23æ©èœãã¹ããã¯ããããªãŒã¹ã¿ã³ãã£ã³ã°æå®
__cpp_lib_forward_like
__cpp_lib_modules
__cpp_lib_move_iterator_concept
__cpp_lib_ranges_as_const
__cpp_lib_ranges_as_rvalue
__cpp_lib_ranges_cartesian_product
__cpp_lib_ranges_repeat
__cpp_lib_ranges_stride
__cpp_lib_start_lifetime_as
ãã®ãªããžã§ã³ïŒR7ïŒã§ã®å€æŽã¯ãLWGã®ãã£ãŒãããã¯ã®åæ ã®ã¿ã§ãã
ãã®ææ¡ã¯æ¢ã«LWGã®ã¬ãã¥ãŒãçµããŠããã次ã®å šäœäŒè°ã§æ祚ã«ãããããäºå®ã§ãïŒC++26ã¿ãŒã²ããã§ãïŒã
<charconv>
ãšstd::char_traits
ãã¯ãããšããããã€ãã®ããããããªãŒã¹ã¿ã³ãã£ã³ã°ã©ã€ãã©ãªæå®ããææ¡ã
以åã®èšäºãåç §
- P2338R0 Freestanding Library: Character primitives and the C library - WG21æ次ææ¡ææžãçºããïŒ2021幎03æïŒ
- P2338R1 Freestanding Library: Character primitives and the C library - WG21æ次ææ¡ææžãçºããïŒ2021幎07æïŒ
- P2338R2 Freestanding Library: Character primitives and the C library - WG21æ次ææ¡ææžãçºããïŒ2021幎11æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ææ¡ããæèšã®èª¿æŽãªã©ã§ãã
ãã®ææ¡ã¯ãC++26ãã¿ãŒã²ãããšããŠLEWGããLWGãžè»¢éãããŠããŸãã
é£æ³ã³ã³ããã®ééçæäœããããã«åºããææ¡ã
以åã®èšäºãåç §
- P2363R0 Extending associative containers with the remaining heterogeneous overloads - WG21æ次ææ¡ææžãçºããïŒ2021幎04æïŒ
- P2363R1 Extending associative containers with the remaining heterogeneous overloads - WG21æ次ææ¡ææžãçºããïŒ2021幎09æïŒ
- P2363R2 Extending associative containers with the remaining heterogeneous overloads - WG21æ次ææ¡ææžãçºããïŒ2021幎12æïŒ
- P2363R3 Extending associative containers with the remaining heterogeneous overloads - WG21æ次ææ¡ææžãçºããïŒ2022幎01æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãset/unordered_set
ã®.insert()
ã«è¿œå ãããªãŒããŒããŒããææ§ã«ãªããªãããã«å¶çŽãè¿œå ããããšã§ãã
ãã®ææ¡ã¯LWGã§ã¬ãã¥ãŒäžã§ãããC++26ãã¿ãŒã²ããã«ããŠããŸãã
â
std::counted_iterator
ãå®å
šã«äœ¿çšå¯èœã«ããææ¡ã
以åã®èšäºãåç §
R1ã§ã®å€æŽã¯ããã£ãŒãããã¯ã«åºã¥ãææ¡å šäœã®ä¿®æ£ãªã©ã§ãã
ãã®ãªããžã§ã³ïŒR2ïŒã§ã®å€æŽã¯
- P2578ãžã®åç §ãåé€
- ææ¡ããèšèšã«ã€ããŠä¿®æ£
- ããã€ãã®ä»£æ¿æ¡ã®æ瀺
ãã®ææ¡ã¯R1以éãåé¡ã解決ããcounted_iterator
ãlazy_counted_iterator
ãšããŠè¿œå ããããã䜿çšããããŒãžã§ã³ã®views::take/views::counted
ãšããŠlazy_take/lazy_counted
ãè¿œå ããããšãææ¡ããŠããŸãã
ãã®äžã§ããã®èšèšã«ã€ããŠæ瀺ãããŠãããªãã·ã§ã³ã¯æ¬¡ã®ãã®ã§ã
lazy_counted_iterator
ãå¯èœãªéãcounted_iterator
ã«è¿ã¥ããrandom_access_iterator
ã«å¯Ÿããæ¯ãèãã¯å€æŽããªãlazy_counted_iterator
ãã€ã³ã¯ãªã¡ã³ãããæãã«ãŠã³ãã0ã«ãªãå Žåã¯åºåºã®ã€ãã¬ãŒã¿ãã€ã³ã¯ãªã¡ã³ãããªãlazy_counted_iterator
ããã¯ãªã¡ã³ãããæãã«ãŠã³ãã0ã®å Žåã¯åºåºã®ã€ãã¬ãŒã¿ããã¯ãªã¡ã³ãããªã- å®è£ ã¯0ã«ãŠã³ãã®æ§ç¯ãæ£ãããã³ããªã³ã°ããªããã°ãªããªã
lazy_counted_iterator
ã¯æã匷ããŠãforward_iterator
ãšãã- ããã«ãã£ãŠããã¯ãªã¡ã³ããèæ ®ããªããŠãè¯ããªã
- 0ã«ãŠã³ãã§æ§ç¯ãããæã¯ãããããèªã¿åããèš±å¯ããªã
- å¯èœãªã®ã¯ãã«ãŠã³ãå€ã®èªã¿åãïŒ
.count()
ïŒãšçµç«¯ãã§ãã¯ïŒ==
ïŒã®ã¿
- å¯èœãªã®ã¯ãã«ãŠã³ãå€ã®èªã¿åãïŒ
- éæ¥åç
§æã«åºåºã®ã€ãã¬ãŒã¿ãã€ã³ã¯ãªã¡ã³ããã
- ããã«ãã£ãŠãéåç
§ã
const
æäœã§ã¯ãªããªããã€ãã¬ãŒã¿ãã³ããŒããŠããã€ã³ã¯ãªã¡ã³ããããšã³ããŒå ãç¡å¹ã«ãªã - 察çãšããŠã
lazy_counted_iterator
ãã³ããŒäžå¯ãšãã
- ããã«ãã£ãŠãéåç
§ã
ãŸããlazy_counted_iterator
ã§ã¯ãã®ã«ãŠã³ãå€ã«äŸåããŠåºåºã®ã€ãã¬ãŒã¿ã®ç¶æ
ãéç·åœ¢ã«å€åããããšãããåºåºã€ãã¬ãŒã¿ãååŸããbase()
ãã©ãããããåé¡ãšãªãããã®ããã®ãªãã·ã§ã³ãæ瀺ãããŠããŸã
.base()
ãæäŸããªãlazy_counted_iterator
ãã³ããŒäžå¯ãšãã- å®è£
ã¯ã
.base()
ã®åŒã³åºãæã«å¿ èŠã«å¿ããŠïŒ0ã«ãŠã³ãã®æïŒã€ãã¬ãŒã¿ãã€ã³ã¯ãªã¡ã³ãããŠè¿ã .base()
ã®åŒã³åºãã¯é 延æäœã§ã¯ãªãlazy_counted_iterator
ãã³ããŒäžå¯ãšããããšã§ãlazy_counted_iterator
ã®ç¡å¹åã«ã€ããŠèæ ®ããªããŠè¯ããªã
- å®è£
ã¯ã
.base()
ãæäŸããããããã«ãã£ãŠä»ã®ã³ããŒãç¡å¹ãšãªãããšãæå®ãã- å®è£
ã¯ã
.base()
ã®åŒã³åºãæã«å¿ èŠã«å¿ããŠïŒ0ã«ãŠã³ãã®æïŒã€ãã¬ãŒã¿ãã€ã³ã¯ãªã¡ã³ãããŠè¿ã
- å®è£
ã¯ã
SG9ã®æ祚ã§ã¯ãlazy_counted_iterator
ãã®ãã®ã«ã€ããŠã¯ãªãã·ã§ã³1ãš2ãéžæããã.base()
ã«é¢ããŠã¯ãªãã·ã§ã³1ãéžæããããããR2ã®æèšã¯ãããåæ ãããã®ã«ãªã£ãŠããŸãã
LEWGã®ã¬ãã¥ãŒãšæ祚ã§ã¯ãlazy_counted_iterator
ã«å¯Ÿããå€æŽãcounted_iterator
ã«çŽæ¥é©çšããããšã«åŒ±ããªãããã³ã³ã»ã³ãµã¹ãåŸãããŠããæ§ã§ãã
äžéšã®æçšãªæšæºã©ã€ãã©ãªã®ã¯ã©ã¹åãããªãŒã¹ã¿ã³ãã£ã³ã°åŠçç³»ã§äœ¿çšå¯èœãšããææ¡ã
以åã®èšäºãåç §
- P2407R0 Freestanding Library: Partial Classes - WG21æ次ææ¡ææžãçºããïŒ2021幎07æïŒ
- P2407R1 Freestanding Library: Partial Classes - WG21æ次ææ¡ææžãçºããïŒ2021幎11æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãææ¡ãHTMLã«ããããšãããªãŒã¹ã¿ã³ãã£ã³ã°å¯Ÿè±¡å€ã®ã¡ã³ãé¢æ°ã¯delete
ããããšæ³šéãã€ããïŒå¯Ÿè±¡ã®ãã®ã«ã¯æ³šéããªãããã«ããïŒããšãstd::forward_like
ãžã®èšåãããªãŒã¹ã¿ã³ãã£ã³ã°æå®ããŸãšããŠè¡ããããªæèšã®è¿œå ããªã©ã§ãã
ãã®ææ¡ã¯ãLWGã®ã¬ãã¥ãŒäžã§ãC++26ãã¿ãŒã²ããã«ããŠããŸãã
説æå°çšã®std::basic-format-string<charT, Args...>
ããŠãŒã¶ãŒãå©çšã§ããããã«ããææ¡ã
以åã®èšäºãåç §
- P2508R0 Exposing
std::basic-format-string
- WG21æ次ææ¡ææžãçºããïŒ2021幎12æïŒ - P2508R1 Exposing
std::basic-format-string
- WG21æ次ææ¡ææžãçºããïŒ2022幎01æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ææ¡ããæèšã®èª¿æŽã®ã¿ã§ãã
ãã®ææ¡ã¯2022幎11æã®konaäŒè°ã§å šäœæ祚ããã¹ããŠãããC++23ã¯ãŒãã³ã°ãã©ããã«å«ãŸããŠããŸãã
æšæºã©ã€ãã©ãªã«ãã¶ãŒããã€ã³ã¿ãµããŒããè¿œå ããææ¡ã
以åã®èšäºãåç §
- P2530R0 Why Hazard Pointers should be in C++26 - WG21æ次ææ¡ææžãçºããïŒ2022幎02æïŒ
- P2530R1 Why Hazard Pointers should be in C++26 - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ã䜿çšäŸãtony-tableã«ããŠã䜿çšããªãæãšãããšãã®æ¯èŒãã§ããããã«ããããšã§ãã
ãã®ææ¡ã¯ãLEWGã®æ祚ããã¹ããŠLWGã«è»¢éãããŠããŸãïŒC++26ã¿ãŒã²ããã§ãïŒã
å¯å€é·åŒæ°é¢æ°ã0åã®åŒæ°ã§å®£èšã§ããããã«ããææ¡ã
以åã®èšäºãåç §
- P2537R0 Relax
va_start
Requirements to Match C - WG21æ次ææ¡ææžãçºããïŒ2022幎02æïŒ - P2537R1 Relax
va_start
Requirements to Match C - WG21æ次ææ¡ææžãçºããïŒ2022幎08æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãC23ã®ä»æ§ïŒN2975ãC23ã«å°å ¥æžã¿ïŒã«åããã2ã€ã®æèšãçšæããããšãšãCWG/EWGã«ãã£ãŠéžæãããªãã£ãæ¹ã®æèšãå·»æ«ã«ç§»åãããããšã§ãã
ãã®ææ¡ã¯ãC++26ãã¿ãŒã²ãããšããŠCWGã§ã¬ãã¥ãŒäžã§ãã
æšæºã©ã€ãã©ãªã«Read-Copy-Update(RCU)ãµããŒããè¿œå ããææ¡ã
以åã®èšäºãåç §
- P2545R0 Why RCU Should be in C++26 - WG21æ次ææ¡ææžãçºããïŒ2022幎02æïŒ
- P2545R1 Why RCU Should be in C++26 - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãææ¡ããæèšã®æ¹åã䜿çšäŸãtony-tableã«ããŠã䜿çšããªãæãšãããšãã®æ¯èŒãã§ããããã«ããããšãå°æ¥çã«æ³å®ãããæ©èœã®æ¡åŒµæ¹åã«ã€ããŠãèšè¿°ããããšãªã©ã§ãã
ãã®ææ¡ã§ã¯ãRCUæ©èœã®å°æ¥çãªæ¡åŒµãæ¹åã«ã€ããŠæ³å®ããããã®ãšããŠæ¬¡ã®ãã®ãæããŠããŸã
- åé€åŠçãåŒã³åºãããã³ã³ããã¹ããšãã®ã¿ã€ãã³ã°ãå¶åŸ¡ããæ¹æ³ã®æäŸ
- RCUãä»ããåå®å
šã¡ã¢ãª
- Linuxã®
SLAB_TYPESAFE_BY_RCU
ã®ãããªãã®
- Linuxã®
std::thread
以å€ã®ã¹ã¬ããã®æåç»é²æ¹æ³ã®æäŸrcu_retire()
ã®ã¡ã¿ããŒã¿åŠçã«é¢ãããå®è£ è ãšãŠãŒã¶ãŒã«å¯Ÿããã¢ããã€ã¹ã®æäŸ- ã¡ã¢ãªãªãŒã¯æ€åºåšãšã®çžäºäœçšã«ã€ããŠ
ãã®ææ¡ã¯ãLEWGã®æ祚ããã¹ããŠLWGã«è»¢éãããŠããŸãïŒC++26ã¿ãŒã²ããã§ãïŒã
ã³ã³ãã©ã¯ã泚éã«æå®ãããæ¡ä»¶åŒãå¯äœçšãæã€å Žåã«ã©ããããã«ã€ããŠãè°è«ããŸãšããææžã
以åã®èšäºãåç §
- P2570R0 On side effects in contract annotations - WG21æ次ææ¡ææžãçºããïŒ2022幎06æïŒ
- P2570R1 On side effects in contract annotations - WG21æ次ææ¡ææžãçºããïŒ2022幎11æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- èšèšåºæºã»ã¯ã·ã§ã³ãæ¡åŒµãç¹ã«ãUBãç¡ãããšãå®å šãšå矩ãšããŠããªãããšã匷調
- P2680R0ã®ã¢ãããŒããæ£ããã³ãŒããå£ãäŸãè¿œèš
- å¥çŽæ¡ä»¶ãå¯äœçšãæã€ããšããªãåé¡ãªã®ãã説æããã»ã¯ã·ã§ã³ãè¿œèš
- å¯äœçšãè©äŸ¡ããããšãä¿èšŒããããšããå°æ¥èãããããã«ãã¢ãŒãïŒäºåæ¡ä»¶ã®ã¿è©äŸ¡ïŒã劚ããå¯èœæ§ãããäºãè¿œèš
- å¯äœçšãæé€ãããC++ã®ä»ã®å Žæã®äŸãè¿œèš
ãªã©ã§ãã
std::string
ãšstd::string_view
ã+
ã§çµåã§ããããã«ããææ¡ã
以åã®èšäºãåç §
- P2591R0 Concatenation of strings and string views - WG21æ次ææ¡ææžãçºããïŒ2022幎05æïŒ
- P2591R1 Concatenation of strings and string views - WG21æ次ææ¡ææžãçºããïŒ2022幎06æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
-
ææ¡ãã
operator+
ã®ã·ã°ããã£ãå€æŽstd::string_view
ã«å€æå¯èœãªãã®ãåãã®ã§ã¯ãªããstd::string_view
ãã®ãã®ãåãããã«ãã
-
ææ¡ãã
operator+
ãhidden friendsã«ãã
std::atomic
ã®notify_one()
ãšwait()
æäœã䜿ãã¥ããããŠããåé¡ã解æ¶ããææ¡ã
以åã®èšäºãåç §
- P2616R0 Making std::atomic notification/wait operations usable in more situations - WG21æ次ææ¡ææžãçºããïŒ2022幎07æïŒ
- P2616R2 Making std::atomic notification/wait operations usable in more situations - WG21æ次ææ¡ææžãçºããïŒ2022幎11æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãatomic_notify_token
ãnotify_token
ã«ååãå€æŽããäºãnotify_token
ã®ãã³ãã¬ãŒããã©ã¡ãŒã¿ãä»»æã®åããatomic
åã«å€æŽããããšãªã©ã§ãã
std::mdspan
ã®éšåã¹ã©ã€ã¹ãååŸããé¢æ°submdspan()
ã®ææ¡ã
以åã®èšäºãåç §
- P2630R0 Submdspan - WG21æ次ææ¡ææžãçºããïŒ2022幎08æïŒ
- P2630R1 Submdspan - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- ã«ã¹ã¿ãã€ãŒãŒã·ã§ã³ãã€ã³ãéžæã«é¢ããè°è«ãè¿œå
strided_index_range
ãstrided_slice
ã«ãªããŒãsubmdspan_mapping
ã®æ»ãå€åã®ããã«ããããã³ã°ãšãªãã»ãããæã€ååä»ãæ§é äœãå°å ¥- mandatesã®åé·ãªå¶çŽãåé€ãããããããšã©ãŒã¡ãã»ãŒãžãåŸãããããã«ãã
- ã¬ã€ã¢ãŠãããªã·ãŒåã®ä¿åããžãã¯ãä¿®æ£
- ç¹ã«ãã©ã³ã¯0ãããã³ã°ã®ã¬ã€ã¢ãŠããä¿åããã¹ã©ã€ã¹æå®ã®ããããã
stride_index_range
ã§ããå Žåã«layout strideãäœæããããã«ãã
- ç¹ã«ãã©ã³ã¯0ãããã³ã°ã®ã¬ã€ã¢ãŠããä¿åããã¹ã©ã€ã¹æå®ã®ããããã
- ãšã¯ã¹ãã³ããstrideããå°ããå Žåã®
strided_slice
ã®ãµããããã³ã°ãšã¯ã¹ãã³ãã®èšç®ãä¿®æ£- äŸç¶ãšããŠããµããããã³ã°ãšã¯ã¹ãã³ãã¯1ãšãªã
strided_slice
æå®ã®ãµããããã³ã°ã¹ãã©ã€ãèšç®ãä¿®æ£strided_slice
ã®strideã0ã®å Žåã«å¯ŸåŠããããã«äºåæ¡ä»¶ãè¿œå
ãªã©ã§ãã
ãã®ææ¡ã¯çŸåšLEWGã®ã¬ãã¥ãŒäžã§ãC++26ã¿ãŒã²ããã«å€æŽãããŠããŸãã
ã ãŒããªã³ãªãŒãªrange
ã®å·ŠèŸºå€åç
§ãviewable_range
ãšãªãããã«ããææ¡ã
以åã®èšäºãåç §
- P2636R0 References to ranges should always be viewable - WG21æ次ææ¡ææžãçºããïŒ2022幎09æïŒ
- P2636R1 References to ranges should always be viewable - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯äž»ã«èª¬æãäŸã®æ¡å ãä¿®æ£ã§ããããã®ææ¡ã¯LEWGã§ã³ã³ã»ã³ãµã¹ãåŸãããªãã£ããããè¿œæ±ã¯åæ¢ãããŠããŸãã
std::mdspan
ã§padding strideããµããŒãããããã®ã¬ã€ã¢ãŠãæå®ã¯ã©ã¹ãè¿œå ããææ¡ã
以åã®èšäºãåç §
- P2642R0 Padded mdspan layouts - WG21æ次ææ¡ææžãçºããïŒ2022幎09æïŒ
- P2642R1 Padded mdspan layouts - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
layout_{left,right}_padded
ã®ç¹æ®åã¯ãã¬ã€ã¢ãŠããããã³ã°ããªã·ãŒèŠä»¶ãæºãããããªãã¢ã«åã§ãããšããèŠå®ãè¿œålayout_{left,right}_padded::mapping
ã®ã³ã³ã¹ãã©ã¯ã¿ã®äºåæ¡ä»¶ã®åçŽålayout_{left,right}_padded::mapping
ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ãè¿œålayout_{left,right}_padded::mapping
ã«layout_(left,right)::mapping
ããã®å€æã³ã³ã¹ãã©ã¯ã¿ãè¿œålayout_{left,right}_padded::mapping
ã«layout_stride::mapping
ããã®å€æã³ã³ã¹ãã©ã¯ã¿ãè¿œålayout_{left,right}_padded::mapping
ã«operator==
ãè¿œå- æ¢åã®ã³ã³ã¹ãã©ã¯ã¿
layout_stride::mapping(const StridedLayoutMapping&)
ã®explicit
æ¡ä»¶å ã®ã¬ã€ã¢ãŠããããã³ã°åã®ãªã¹ãã«layout_{left,right}_padded
ãè¿œålayout_{left,right}_padded::mapping
ããlayout_stride::mapping
ãžã®å€æã¯explicit
ã§ã¯ãªã
ãªã©ã§ãã
C++å®è£ ïŒã³ã³ãã€ã©ïŒãšåšèŸºããŒã«ã®çžäºã®ããåãã®ããã®åœéèŠæ Œãçºå¹ããææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯ãISçºè¡ã®ããã®ã¿ã€ã ã©ã€ã³ãšããã»ã¹ãè¿œå ããããšãªã©ã§ãã
Ecosystem ISã¯2023幎ããå§ãŸã2幎ããšã®ãªãªãŒã¹ãµã€ã¯ã«ã§çºå¹ããŠããããšãç®æããŠããŠãæåã®ISãçºå¹ããããã®ã¹ã±ãžã¥ãŒã«ã次ã®ããã«ããŠããŸã
- 2023/02 : èšç»
- æåã®ISã®éçºèšç»ã®å®äº
- åçã«äœãå«ãŸããããæ€èš
- 2023/03 : æåã®ãã©ããäœæ
- æåã®æå°éã®ãã©ãããäœæ
- ãã®ãã©ããã«ã¯ãæäœ1ã€ã®ææ¡ãçµ±åãããŠããŠãã®ããã®ãã®ãæŠèŠãèšèŒãããŠãã
- äœæ¥ã®ãã§ãã¯ãã€ã³ããšããããã«ãEWGã®æ¿èªãåŸã
- 2024/02 : ææ¡
- æåã®ISçºå¹ã®ããã®æ£åŒãªææ¡ãäœæãã
- ããã«ã¯ãæåã®ISã®ãã©ããã®ã»ãŒå®å šãªãã®ãå«ãŸãã
- 2025/01 : CDäœæå®äº
- NBã³ã¡ã³ãåéã®ããã®Committee Draftãæ¿èªãã
- 2025/02 : DISäœæå®äº
- å¯ããããNBã³ã¡ã³ãã解決ããFinal Draft International Standardãæ¿èªãã
ãã®åŸã2幎ããšã«åæ§ã®ã¹ã±ãžã¥ãŒã«ã§Ecosystem ISãæ¹åããŠããäºå®ã§ããC++æ¬äœãšæ¯èŒãããšæ¬¡ã®ããã«ãªããŸã
ãã®äœæ¥ã®ããã®WG21ã«ãããããã»ã¹ã¯ãWG21ã®çŸåšã®ããã»ã¹ã«èŠªåããããã«æ¬¡ã®2ã€ã®ããã»ã¹ãææ¡ããŠããŸã
- ããŒãã¹ãã©ãã
- Tooling Study Group (SG15)ã§åæéçºåã³ã¬ãã¥ãŒ
- ãã®åŸãEWG/LEWGã§ã®ã¬ãã¥ãŒãšæ¿èª
- ãããããæèšããã»ã¹ã®å®æçãªã¬ãã¥ãŒãšæ¿èªãç¶ã
- 䞊è¡
- éçºåã³ã¬ãã¥ãŒã¯ãé©å®æ¢åã®SGããéå§ã§ãã
- ç¶ããŠãTooling Working Group (TWG)ã«ããã¬ãã¥ãŒãšæ¿èªãè¡ããã
- TWGã¯ISäºæ ã®æèšã®æ€èšãè¡ããWG21å šäœæ祚ã®ããã®äœæ¥ãæ ã
ããŒãã¹ãã©ããããã»ã¹ã¯æåã®ISãäœæããããã«äœ¿çšãããã®åŸã¯äžŠè¡ããã»ã¹ã«åãæ¿ããŸãã
䞊è¡ããã»ã¹ã¯ãçŸåšã®WG21äœæ¥ãããŒãããŒã¹ã«æ¬¡ã®ãããªãã®ã«ãªããŸã
å¥çŽããã°ã©ãã³ã°æ©èœã«é¢ããTechnical Specificationãçºå¹ããææ¡ã
以åã®èšäºãåç §
- P2659R0 A Proposal to Publish a Technical Specification for Contracts - C++WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
- P2659R1 A Proposal to Publish a Technical Specification for Contracts - C++WG21æ次ææ¡ææžãçºããïŒ2022幎11æïŒ
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- GCCãå¥çŽæ©èœãå®è£ ããã®ãåããŠãMotivationãšAppendixãæŽæ°
- ã¿ã€ã ã©ã€ã³ã®ã¢ããããŒã
ãªã©ã§ãã
P2675R1 LWG3780: The Paper (format's width estimation is too approximate and not forward compatible)
std::format
ã®æåå¹
ã®èŠå®ãæ¹åããææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- æšæºãã¯ã€ããšããŠäºçŽããã³ãŒããã€ã³ãã¯ãã®ããã«æ±ããªãããšãæ瀺
- ãµã³ãã«ãšããŠç€ºããçµæã®çæã«äœ¿çšãããã¡ã€ã«ãžã®ãªã³ã¯ãè¿œå
- é¢é£ãããæ¢åã®ã¿ãŒããã«ã«ãããå®è£ ãžã®ãªã³ã¯è¿œå
- æçšã§ã¯ãªãã£ãã¹ã¯ãªãŒã³ã·ã§ãããåé€
ãªã©ã§ãã
auto
ã«ããç°¡æé¢æ°å®£èšæ§æã«ãããŠãååãååŸå¯èœã«ããææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- æšå¥šããã·ã³ãã«ã
~
ãã:
ã«å€æŽ - å¯èœãªè¡šèšæ¹æ³ã«ã€ããŠã®è¿œå ã®è°è«ãè¿œèš
- ãŠãããŒãµã«åç §ïŒãã©ã¯ãŒãã£ã³ã°ãªãã¡ã¬ã³ã¹ïŒã«ã€ããŠã®è°è«ã®è¿œèš
ãã®ææ¡ã®R1ã¯å
¬éãããŠããŸããããã©ãããããã§ã¯auto
ããååãååŸããæ§æãšããŠauto~T
ã®ãããªãã®ãææ¡ããŠããããã§ããããã¯R0ã§ææ¡ããŠããauto{T}
ãdecay-copyæ§æïŒauto{x}
ïŒãšè¡çªããããšã«ãããã®ã§ããã®ãªããžã§ã³ã§ã¯ããã:
ã«çœ®ãæããŠããŸãã
// R0ïŒauto{x}ãdecay-copyãšè¡çªããïŒ
[](auto{T}&& x) { return f(std::forward<T>(x)); }
// R1
[](auto~T && x) { return f(std::forward<T>(x)); }
// R2
[](auto:T && x) { return f(std::forward<T>(x)); }
ãŸã 確å®ã§ã¯ãªãããã®ææ¡ã§ã¯ä»ã®éžæè¢ãšããŠ$ã@ãããã·ã¥ã®ã»ããauto<T>
ãT:auto
ãªã©ãåè£ãšããŠæããŠããŸãã
C++ã®å¥çŽããã°ã©ãã³ã°æ©èœã¯å®å šç¬¬äžã§èšèšãããã¹ãããšããæèšã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã¯ãåºæ¬çãªãšããã¯å€ãã£ãŠããªãããã§ããã»ãšãã©R0ãšå¥ç©ã«ãªã£ãŠããŸããç¹ã«ãå·»æ«ã«P2700ã®åã«å¯ŸããåçãèšãããŠããŸãã
- P2700R0 Questions on P2680 âContracts for C++: Prioritizing Safetyâ - WG21æ次ææ¡ææžãçºããïŒ2022幎11æïŒ
- P2680 é²è¡ç¶æ³
ã¢ãããã¯æäœãé©çšããåç
§ãè¿ãmdspan
ã®ã¢ã¯ã»ããµã§ãããatomic_accessor
ã®ææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- ç¹å®ã®ã¡ã¢ãªãªãŒããŒãæå®ãã
std::atomic_ref
ã§ããatomic-ref-bounded
ã説æå°çšãã³ãã¬ãŒããšããŠè¿œå atomic_ref_relaxed, atomic_ref_acq_rel, atomic_ref_seq_cst
ã®3ã€ã®ãšã€ãªã¢ã¹ãè¿œåbasic-atomic-accessor
説æå°çšãã³ãã¬ãŒããè¿œåatomic_accessor_relaxed, atomic_accessor_acq_rel, atomic_accessor_seq_cst
ã®3ã€ã®ãã³ãã¬ãŒããè¿œå
R0ã§ã¯ãatomic_accessor
ã§äœ¿çšããstd::atomic_ref
ã®ããã©ã«ãã®ã¡ã¢ãªãªãŒããŒãéå°ã§ããããå€æŽã§ããªãããšãåé¡ã«ãªã£ãŠããŸããã
ãã®ãªããžã§ã³ã§ã¯ãã®å¯Ÿå¿ã®ããã«ãã¡ã¢ãªãªãŒããŒæå®ããã³ãã¬ãŒããã©ã¡ãŒã¿ã§åãåãããŒãžã§ã³ã®std::atomic_ref
ãatomic-ref-bounded
ãšããŠèª¬æå°çšã§è¿œå ãããã®èšå®æžã¿ãšã€ãªã¢ã¹ãšããŠatomic_ref_relaxed, atomic_ref_acq_rel, atomic_ref_seq_cst
ãè¿œå ããŸãã
ãããŠã䜿çšããatomic_ref
ãè¿œå ã®ãã³ãã¬ãŒããã©ã¡ãŒã¿ãšããŠåãåãããšã§ã¡ã¢ãªãªãŒããŒãæå®ããbasic-atomic-accessor
ãè¿œå ããatomic_accessor
åã³atomic_accessor_relaxed, atomic_accessor_acq_rel, atomic_accessor_seq_cst
ã¯ãã®èšå®æžã¿ãšã€ãªã¢ã¹ãã³ãã¬ãŒããšããŠå®çŸ©ãããŸãã
namespace std {
// ã¡ã¢ãªãªãŒããŒæå®ãåããããšã®ã§ããatomic_refïŒèª¬æå°çšïŒ
template <class T, memory_order MemoryOrder>
struct atomic-ref-bounded {
...
};
// ç¹å®ã®ã¡ã¢ãªãªãŒããŒã«ããatomic_refïŒãããã¯èª¬æå°çšã§ã¯ãªãïŒ
template<class T>
using atomic_ref_relaxed = atomic-ref-bounded<T, memory_order_relaxed>;
template<class T>
using atomic_ref_acq_rel = atomic-ref-bounded<T, memory_order_acq_rel>;
template<class T>
using atomic_ref_seq_cst = atomic-ref-bounded<T, memory_order_seq_cst>;
// atomic_accessorã®ããŒã¹åïŒèª¬æå°çšïŒ
template <class ElementType, class ReferenceType>
struct basic-atomic-accessor {
...
};
// ããã©ã«ãã®atomic_accessorãstd::atomic_refã䜿çš
template <class ElementType>
using atomic_accessor = basic-atomic-accessor<ElementType, atomic_ref<ElementType>>;
// ã¡ã¢ãªãªãŒããŒãã«ã¹ã¿ã ããatomic_accessor
template <class ElementType>
using atomic_accessor_relaxed = basic-atomic-accessor<ElementType, atomic_ref_relaxed<ElementType>>;
template <class ElementType>
using atomic_accessor_acq_rel = basic-atomic-accessor<ElementType, atomic_ref_acq_rel<ElementType>>;
template <class ElementType>
using atomic_accessor_seq_cst = basic-atomic-accessor<ElementType, atomic_ref_seq_cst<ElementType>>;
}
atomic_ref_relaxed, atomic_ref_acq_rel, atomic_ref_seq_cst
ã®3ã€ã¯ãã¡ã¢ãªãªãŒããŒãå€æŽãããstd::atomic_ref
ãšããŠè¿œå ããããŠãŒã¶ãŒã䜿çšããããšãã§ããŸãã
P2680R0ã§æå±ãããŠããå¥çŽæ¡ä»¶ã®å¯äœçšã®æ±ãã«ã€ããŠã幟ã€ãã®çåç¹ãæåºããææžã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- ç·©åãããå¥çŽæ¡ä»¶ãšããã§ãªããã®ã®äž¡æ¹ã®ååšã説æããããã®ä¿®æ£
- Q1.4, Q5.1, Q5.2, Q5.9ã«ã€ããŠãæ確åããã質åãæ¡åŒµ
- Q5.10ã«æ°ãã質åãè¿œå
ãªã©ã§ãã
ããïŒå€åR0ïŒã«å¯Ÿããåçã¯ãå°ãäžã®P2680R1ã§ãªãããŠããŸãã
â
std::format
ã®ãšã¹ã±ãŒãåºåïŒ?
ïŒæã®åºåæ¹æ³ãä¿®æ£ããææ¡ã
std::format
ã®?
æå®ã¯ãC++23ã§range
åºåãµããŒãïŒP2286R8ïŒãšåæã«ããã®ã³ã°ããããã°æã®åºåã®ããã«è¿œå ããããã®ã§ãã
?
ã«ããæå®ã¯ç¹ã«æå/æååã®åºåæã«æå¹ãªãã®ã§ãå
¥åã®æååããã®ãŸãŸïŒäººéã®èŠèªæ§ãåªå
ããŠïŒåºåããŸããåºåã¯ãŸããåºåæååå
šäœã"
ã«ãããããŠåºåãããå
¥åãããæåã§å¯Ÿå¿ãããšã¹ã±ãŒãã·ãŒã±ã³ã¹ãããæåïŒ\t \n \r " \
ã®5ã€ïŒã¯å¯Ÿå¿ãããšã¹ã±ãŒãã·ãŒã±ã³ã¹ã«çœ®æãããŠåºåãããŸãããŸãããŠãã³ãŒãæåã®äžã§ãåºåã§ããªãïŒèŠããªãïŒãã®ãªã©ããç¡å¹ãªæåãšãªããã®ããšã¹ã±ãŒããããŠïŒ\u{xxxx}
ã®åœ¢ã§ïŒåºåãããŸãã
int main() {
std::cout << std::format("{:?}", "hello") << std::endl;
// "hello"ãšåºå
std::cout << std::format("{:?}", R"("hello"\n)") << std::endl;
// "\"hello\"\n"ãšåºå
}
ãã®ãã©ãŒãããæã®ãšã¹ã±ãŒãã®æ¯ãèãã¯ãå ¥åæååã1æåã¥ã€èŠãŠãã£ãŠãæåã眮ææ¡ä»¶ã«åèŽããå Žåã«å¯Ÿå¿ããè¡šçŸã«çœ®æïŒãšã¹ã±ãŒãïŒãããŠåºåããããããªåœ¢ã§èšè¿°ãããŠããŸãã
ãã ããã®ãã©ãŒãããæ¹æ³ã¯ãäœãç®çãšããŠãã©ãŒãããããã®ããäžæçã ã£ãããã§ããã€ãŸãããã®ãšã¹ã±ãŒãã¯ãå ¥åæååã人éã«ãšã£ãŠèªã¿ããã圢ã§åºåããããšãæå³ããŠããã®ããå ã®ãšã³ã³ãŒãã£ã³ã°ã«ãããæåè¡šçŸãèŠèªå¯èœãªåœ¢ã§åºåããããšãæå³ããŠããã®ãããäžéæã§ãããã«ãã£ãŠäžéšã®æåã®æé©ãªãšã¹ã±ãŒããå€åããŸããããã¯C++23 CDã«å¯Ÿããã¢ã¡ãªã«/ãã©ã³ã¹ããã®NBã³ã¡ã³ãã«ãã£ãŠææãããŸããã
ãã®ææ¡ã¯ã?
ã«ãã£ãŠãšã¹ã±ãŒããããåºåæååã®æå³ããå
¥åæå/æååãC++ã³ãŒãäžã§æå/æååãªãã©ã«ãšããŠèšè¿°ããå Žåã®æååãåçŸããããšã«ããããšãæ確åããããã«ããšã¹ã±ãŒãæ¹æ³ãä¿®æ£ãããã®ã§ãã
ãã®ææ¡ã¯ãã®åé¡ã«é¢ããSG16ã®æ祚ã«ãã£ãŠç¢ºèªãããäºé ã«å¯ŸããŠæšæºã®æèšãæäŸãããã®ã§ãSG16ã§ã¯æ¬¡ã®ããšã確èªãããŸãã
?
ã«ãã£ãŠãšã¹ã±ãŒããããæååã¯ãã®ãŸãŸæå/æååãªãã©ã«ãšããŠäœ¿çšã§ãã- ãšã¹ã±ãŒããããåºåæååã¯ãæååãªãã©ã«ãšããŠäœ¿çšããããšãã«å ¥åæååãåçŸããããšã®ã§ããæååãšãªã
- ãšã¹ã±ãŒããããæååã¯èŠèŠçã«æ確ãªïŒäººéã«ãšã£ãŠèªã¿åããããïŒæååãçæããªã
- åºåãæåã衚瀺ã§ããªãæåã¯åŒãç¶ããšã¹ã±ãŒãããã
ããã«ããäž»ãªå€æŽã¯ã次ã®ããã«ãªããŸã
- ãŠãã³ãŒãã®çµåæåã¯ãåºåæååã®çŽåã«çµåå¯èœãªæåãçŸããŠããå Žåã«ãšã¹ã±ãŒããããªã
- çµåæåãšã¯ã
Grapheme_ÂExtend=Yes
ãšãããŠãã³ãŒãããããã£ãæã€æå - çµåå¯èœãªæåãšã¯ããšã¹ã±ãŒããããªãæåãããã¯ãããã«çµåããŠããçµåæåã®ããš
- çµåæåãšã¯ã
ææ¡ææžããããµã³ãã«ã³ãŒã
string s0 = format("[{}]", "h\tllo"); // s0ã®çµææåå㯠[h llo] ïŒéãšã¹ã±ãŒãåºåïŒ
string s1 = format("[{:?}]", "h\tllo"); // s1ã®çµææåå㯠["h\tllo"] ïŒã¿ãæåã\tã«ãšã¹ã±ãŒãïŒ
string s3 = format("[{:?}, {:?}]", '\'', '"'); // s3ã®çµææåå㯠['\'', '"'] ïŒ\ ãš " ã¯ãšã¹ã±ãŒããããŠåºåãããïŒ
// 次ã®äŸã§ã¯UTF-8ãšã³ã³ãŒãã£ã³ã°ãä»®å®
string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9)); // s4ã®çµææåå㯠["\u{0} \n \t \u{2} \u{1b}"]
string s5 = format("[{:?}]", "\xc3\x28"); // s5ã®çµææåå㯠["\x{c3}("] ïŒäžæ£ãªUTF-8æååã®ã±ãŒã¹ïŒ
string s6 = format("[{:?}]", "\u0301"); // s6ã®çµææåå㯠["\u{301}"]
string s7 = format("[{:?}]", "\\\u0301"); // s7ã®çµææåå㯠["\\\u{301}"]
string s8 = format("[{:?}]", "e\u0301\u0323"); // s8ã®çµææåå㯠["eÌÌ£"]
ãã®ææ¡ã«ãããŠæ¯ãèããæ確åãããã®ã¯ãäžã®3ã€ã®äŸïŒs6, s7, s8
ïŒã§ãããŸãã\u0301
ãš\u0323
ã¯ãã€ã¢ã¯ãªãã£ã«ã«ããŒã¯ãšããçµåæåïŒã¢ã«ãã¡ãããã®äžäžã«ã€ãæåïŒã§ãã
s6
ã¯ãçµåæåã«éçµåæåïŒçµå察称ïŒãå
è¡ããŠããªãããããšã¹ã±ãŒããããŠåºåãããŠããŸããs7
ã¯ããšã¹ã±ãŒããããæåãå
è¡ããŠããããããšã¹ã±ãŒããããŠåºåãããŠããŸããs8
ã¯ãšã¹ã±ãŒããããªãæåïŒe
ïŒãå
è¡ããŠãããã\u0301
ïŒäžä»ãã®,
ïŒãçµåããçµåããçµåæåãå
è¡ããŠãããã\u0323
ïŒäžä»ãã®.
ïŒãçµåããŠåºåãããçµæã¯èŠãç®1æåã«ãªãããšã¹ã±ãŒããããæåã¯ãããŸããã
- FR 005-134 22.14.6.4 [format.string.escaped] Aggressive escaping
- US 38-098 22.14.6.4p1 [format.string.escaped] Escaping for debugging and logging
std::format
- cpprefjp- P2286R8 Formatting Ranges
- P2713 é²è¡ç¶æ³
std::bind_front
ãšstd::bind_back
ã«NTTPãšããŠåŒã³åºãå¯èœãªãã®ãæž¡ããªãŒããŒããŒããè¿œå ããææ¡ã
ããã¯ãP2511ã§ææ¡ãããŠããstd::nontype
ã®ã¢ãããŒãïŒã¡ã³ããã€ã³ã¿ãNTTPãšããŠæž¡ãïŒãstd::bind_front
ãšstd::bind_back
ã§ã§ããããã«ããããšãããã®ã§ããã€ã³ãããCallableãªããžã§ã¯ãã第äžåŒæ°ãããã³ãã¬ãŒããã©ã¡ãŒã¿ãžç§»åãããŸãã
struct S {
int func(int, char, std::string_view);
};
int main() {
// çŸåšïŒC++20
auto bf1 = std::bind_front(&S::func, 20, 'a');
// ãã®ææ¡
auto bf2 = std::bind_front<&S::func>(26, 'a');
}
ãã®ãã³ãã¬ãŒããã©ã¡ãŒã¿ã«ã¯ã¡ã³ããã€ã³ã¿ã ãã§ãªãCPOã®ãããªãã®ã䜿çšã§ããŸãã
#include <compare>
int main() {
// çŸåšïŒC++20
auto bf1 = std::bind_front(std::strong_order, 20);
// ãã®ææ¡
auto bf2 = std::bind_front<std::strong_order>(26);
}
ãã®ææ¡ã«ããã¡ãªããã¯
- ã¹ãã¬ãŒãžå®¹éã®åæž
- ã¡ã³ãé¢æ°ãšãã®å¯Ÿè±¡ãªããžã§ã¯ãããã€ã³ãããå Žåããã®çµæãªããžã§ã¯ãã¯å
ã®ãªããžã§ã¯ãããã倧ãããªãã
std::function
çã®SBOã®ãµã€ãºãè¶ ããŠããŸã - åŒã³åºãããã¡ã³ãé¢æ°çã¯ã³ã³ãã€ã«æã«ããã£ãŠããããšãã»ãšãã©ã ããçŸåšã®å®è£ ã§ã¯åé¿ã§ããªã
- NTTPãšããŠã¡ã³ããã€ã³ã¿ã転éããããšã§ããã®ã¹ãã¬ãŒãžãµã€ãºãåæžã§ãã
- ã¡ã³ãé¢æ°ãšãã®å¯Ÿè±¡ãªããžã§ã¯ãããã€ã³ãããå Žåããã®çµæãªããžã§ã¯ãã¯å
ã®ãªããžã§ã¯ãããã倧ãããªãã
- å®è£
ã®åçŽåãšãããã°æ
å ±ã®ã¹ãªã å
- ã¹ããŒãã¬ã¹ã©ã ãåŒã®ãããªç©ºã®callableãªããžã§ã¯ããå¹ççã«ä¿åããããã«è€éãªããšïŒEBOã®æå¹åïŒãããå¿ èŠããªããªã
std::move()
çããããã°æã«æãäžããªãå Žåãæçžããããšã³ãã£ãã£ã«ã¢ã¯ã»ã¹ããéã«ãããã°æ å ±ãè¥å€§åãããäžéå±€ãç¡ããªã
std::bind_front
ãšstd::bind_back
ã®å¯èªæ§åäžinvoke(func, a, b, ...)
ã®ãããªåŒã³åºãã¯C++ã«ãããŠäžè¬çã«ãªãã€ã€ããããäŸç¶ãšããŠfunc(a, b, ...)
ã®æ¹ãããé¢æ°åŒã³åºãã®è¡šçŸãšããŠèªç¶ã ãšæãã人ãå€ããšæããã- ãã®ããã
bind_front(func, a, b)
ãããbind_front<func>(a, b)
ã®æ¹ãèªç¶ã§ãããšæãããããããªã - ãŸããcallableã¿ãŒã²ãããšããã«æçžããåŒæ°ãèŠèŠçã«åé¢ãããŠãããããèŠããããªã
ãã®ææ¡ã§ã¯ãåæ§ã®å€æŽãstd::not_fn
ã«å¯ŸããŠãè¡ãããšãææ¡ããŠããŸãã
- P2511R0 Beyond operator(): NTTP callables in type-erased call wrappers - C++WG21æ次ææ¡ææžãçºããïŒ2022幎01æïŒ
- P2714 é²è¡ç¶æ³
C++åšèŸºããŒã«ããEcosystem ISã«ã©ãã»ã©æºæ ããŠããã®ããäºãã«éä¿¡ããæ段ãæšæºåããææ¡ã
Ecosystem ISã¯C++ã®ããŒã«ïŒã³ã³ãã€ã©ããã«ãã·ã¹ãã ãããã±ãŒãžãããŒãžã£ãéç解æããŒã«ãªã©ïŒç°å¢ãæŽåããããã®ç¬ç«ããæšæºèŠæ Œã§ãP2656ã§æ¹åæ§ãææ¡ãããŠããŸããEcosystem ISã«WG21ãšããŠåãçµãã§ããããšã¯åæãããŠããããã§ãã
Ecosystem ISã¯æ¢åã®ããŒã«ãåŠå®ãWG21ã§ããŒã«ãäœãäžãããã®ã§ã¯ãªããããŒã«ãšããŒã«ã®éã®çžäºéä¿¡ã«å¿ èŠãªéšåãæšæºåããããšãããã®ã§ãã
Ecosystem ISãC++ãã®ãã®ãšåæ§ã«åŸã ã«é²åããŠããããšãèãããšãEcosystem ISã«ãããŒãžã§ã³ãçãŸããEcosystem ISã«æºæ ããC++ããŒã«ã¯ããæç¹ã§ã¯ç¹å®ããŒãžã§ã³ã®Ecosystem ISãå®è£ ããããšã«ãªãã§ããããEcosystem ISã®ç®çã¯ãã®ãããªããŒã«ã®çžäºã®ããåãã®æšæºåã«ããã®ã§ãäºããæ³å®ããEcosystem ISããŒãžã§ã³ãç°ãªãå Žåã«ãããç¥ãæ段ããªãããšã¯åé¡ãšãªããŸãã
ãã®ææ¡ã¯ãããŒã«ãå®è£ ããEcosystem ISã®ããŒãžã§ã³æ å ±ãååŸã§ããã¡ã«ããºã ãEcosystem ISã«æåããçµã¿èŸŒãã§ããããšãææ¡ãããšãšãã«ãããããŒã«ãå¥ã®ããŒã«ã®Ecosystem ISã®æ©èœã䜿çšããå Žåã«ã©ã®ããŒãžã§ã³ãæ³å®ããŠããã®ããåæã«äŒéã§ããã¡ã«ããºã ã«ã€ããŠãææ¡ããŠããŸãã
ãã®ææ¡ã¯æ¬¡ã®2ã€ã®æ©èœãææ¡ããŠããŸã
- ã€ã³ããã¹ãã¯ã·ã§ã³ïŒIntrospectionïŒ
- å®è£ ããããŒãžã§ã³ã«ã€ããŠçžæã«å ±åãã
- 宣èšïŒDeclarationïŒ
- å¿ èŠãšããããŒãžã§ã³ãšãšãã£ã·ã§ã³ãçžæã«æå®ãã
ã€ã³ããã¹ãã¯ã·ã§ã³ã«ãã£ãŠãããŒã«ã¯çžæã®ããŒã«ãç¹å®ã®æ©èœãå®è£ ããŠããããåãåãããããšãã§ããŸããåãåãããåããããŒã«ã¯ãµããŒãããŠããæ©èœã®ç¯å²ã§å¿çãããäœãå¿çããŸãããå¿çããã£ãå Žåããã®æ å ±ã䜿çšããŠãEcosystem ISæšæºã«åŸã£ãŠçžæããŒã«ãšã®ãããªãããåããé²ããããšãã§ããŸãã
宣èšã«ãã£ãŠãããŒã«ã¯ç¹å®ã®æ©èœã«ãã£ãŠããåãããæã®ãã®æ©èœã«ã€ããŠã®ããŒãžã§ã³ãæå®ã§ããŸããçžæããŒã«ããã®å®£èšãåãå ¥ããå Žåã¯ããã®æ©èœã䜿çšããŠããåããé²ããããšãã§ããŸãã
ã©ã¡ãã®æ©èœã®å Žåããããã¯ããŒã«ã®ã³ãã³ãã©ã€ã³åŒæ°ã§æž¡ããè¿çã¯JSONã§è¿ããŸãã
ã€ã³ããã¹ãã¯ã·ã§ã³ã®å Žåã¯--std-info
ãšããã³ãã³ãã©ã€ã³åŒæ°ã䜿çšããŸã
tool --std-info
ããã«å¯Ÿããå¿çã¯äŸãã°æ¬¡ã®ããã«ãªããŸã
{
"$schema": "https://raw.githubusercontent.com/cplusplus/ecosystem-is/release/schema/std_info-1.0.0.json",
"std:info": "[1.0.0,2.5.0]"
}
ãã®åãåããã¯Ecosystem ISã®å šãŠã®æ©èœã«ã€ããŠè¡ãããçµæããã¹ãŠã®æ©èœã«ã€ããŠåž°ã£ãŠããŸããããããå Žåã«ãã£ãŠã¯ç¹å®ã®æ©èœã«ã€ããŠã ãåãåãããããæ¹ãå¹ççãªå Žåããããã®ããã®å¶éä»ãã®åãåããããµããŒãããŠããŸã
å¶éä»ãåãåããã--std-info
ã§è¡ããŸãããæ©èœã瀺ãååãšããŒãžã§ã³ãåæã«æå®ããŸã
tool "--std-info=std:info==[1.0.0,2.1.0)"
ããã¯--std-info
ãã®ãã®ã®ããŒãžã§ã³ã®åãåããã§ã
ããã«å¯Ÿããå¿çã¯äŸãã°æ¬¡ã®ããã«ãªããŸã
{
"$schema": "https://raw.githubusercontent.com/cplusplus/ecosystem-is/release/schema/std_info-1.0.0.json",
"std:info": "[1.5.0,2.0.0]"
}
ãã®å Žåãçžæã®ããŒã«ã¯èŠæ±ãããããŒãžã§ã³ïŒ1.0.0 ~ 2.1.0ïŒã®ãµãã»ããïŒ1.5.0 ~ 2.0.0ïŒããå®è£ ããŠããªããšãã£ãŠããŸãã
ãŸãè€æ°åæã«åãåãããããšãã§ããŸã
tool "--std-info=std:info=[1.0.0,2.1.0)" "--std-info=gcc:extra[2.0.0,2.1.0]"
ãã®çµæã¯äŸãã°æ¬¡ã®ããã«ãªããŸã
{
"$schema": "https://raw.githubusercontent.com/cplusplus/ecosystem-is/release/schema/std_info-1.0.0.json",
"std:info": "[1.0.0,2.0.0)",
"gcc:extra": "2.1.0"
}
ãã®çµæãåããŠã䜿çšããæ©èœã®ããŒãžã§ã³ãæå®ïŒå®£èšïŒããã«ã¯ã䜿çšããæ©èœãšå
±ã«--std-decl
ã«ãã®æ©èœãšèŠæ±ããŒãžã§ã³ãæå®ããããã«ããŸãã
tool "--std-decl=std:info=2.0.0" "--std-decl=gcc:extra=2.1.0" --std:info --gcc:extra...
ããã§ã¯ã--std:info
ã¯2.0.0ã䜿çšãã--gcc:extra
ã¯2.1.0ã䜿çšããããã«çžæããŒã«ã«èŠæ±ããŠããŸãã
ãããã®è¿çã®ãã©ãŒããããããŒãžã§ã³æå®ã®ãã©ãŒããããªã©ã¯ããã®ææ¡ã§ã¯JSON Schemaã®åœ¢ã§èŠå®ããããšãææ¡ããŠããŸãã
èªåèšæ¶åæéã®å€æ°ãåæåãããªãå Žåã«åžžã«ãŒãåæåãããããã«ããææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã¯ãåºæ¬çãªãšããã¯å€ãã£ãŠããŸãããR0ããå šäœçã«å€§ããæžãçŽãããŠããŸããç¹ã«ããªããã¢ãŠãïŒæªåæåã®ãŸãŸã«ããŠããïŒã®æ¹æ³ã«ã€ããŠã®æ€èšãèšèªã®å€æŽã§ã¯ãªãå¥ã®æ段ã«ãã£ãŠéæããããšã«ã€ããŠãªã©ãè¿œå ãããŠããŸãã
2æã®ã€ãµã¯ã¢äŒè°ã«ãããEWGã®ã¬ãã¥ãŒã§ã¯ããªããã¢ãŠãã®æ¹æ³ãšããŠã¯std::uninitialized
ãšããç¹å¥ãªã©ã€ãã©ãªå€æ°ã«ãããã®ã奜ãŸããŠããããã§ãã
çŸåšãã³ã°ãªã³ã°åç §ãçæããŠãããã®ã«ã€ããŠãå®æ°åæåå¯èœãªãã®ãæé»ç/æ瀺çã«å®æ°åæåããææ¡ã
ãã®ææ¡ã¯ã以åã®P2658ãšP2623ã®ææ¡ãããå®æ°åæåé¢é£ã®éšåãããŒãžãããã®ã§ããããããã«ã€ããŠã¯ä»¥åã®èšäºãåç §
- P2623R0 implicit constant initialization - WG21æ次ææ¡ææžãçºããïŒ2022幎07æïŒ
- P2658R0 temporary storage class specifiers - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ã»ãšãã©å®æ°ãšåçã§ãããªããå®æ°ã§ã¯ãªãããã«ãµãšãã䜿ãæ¹ã®ééãã§ãã³ã°ãªã³ã°åç §ãçæãå®å šæ§ãæããŠããã±ãŒã¹ãC++ã®ãã¡ãã¡ã§èŠãããŸãããã®ãããªå®æ°ãšã¿ãªãããã®ãå®æ°åæåïŒã³ã³ãã€ã«æã«åæåïŒããããšã§éçã¹ãã¬ãŒãžã«é 眮ãããã³ã°ãªã³ã°åç §ãåé¿ããã®ããã®ææ¡ã®ç®çã§ãã
std::string_view sv1 = "hello world"; // ok
// å
±ã«ãã³ã°ãªã³ã°åç
§ãšãªã
std::string_view sv2 = "hello world"s; // UBããã®ææ¡ã«ãã£ãŠæé»å®æ°åæå
std::string_view sv3 = constinit "hello world"s; // æ瀺çã«å®æ°åæåãè¡ã
struct X {
int a, b;
};
const int& get_a(const X& x) {
// å
¥åã«ãã£ãŠã¯ãã³ã°ãªã³ã°åç
§ãè¿ã
return x.a;
}
const int& a = get_a({4, 2}); // UBãaã¯ãã³ã°ãªã³ã°åç
§ãšãªã
a; // ãã®ææ¡ã«ãã£ãŠä¿®æ£ããããš4ãä¿æ
std::generator<char> each_char(const std::string& s) {
for (char ch : s) {
co_yield ch;
}
}
int main() {
auto ec = each_char("hello world"); // ã³ã«ãŒãã³ããå¶åŸ¡ãæ»ã£ãæç¹ã§ãã³ã°ãªã³ã°åç
§ãšãªãããã®ææ¡ã«ãã£ãŠæé»å®æ°åæå
for (char ch : ec) {
std::print(ch);
}
}
ãã®äŸã§åé¡ãšãªã£ãŠããåæã¯å šãŠããã®ææ¡ã«ããæé»å®æ°åæåã«ãã£ãŠãã³ã°ãªã³ã°åç §ãçæããªããªããŸãã
ãã®ææ¡ã¯ãããã®äŸãé²æ¢ã§ããããã«ãªãäžæ¹ã§ãåãããã«ãã³ã°ãªã³ã°åç §ãçæããå šãŠã®å Žåã«ãããé²æ¢ã§ããããã§ã¯ãããŸããããããŸã§ãäžéšã®ã±ãŒã¹ã§ãã³ã°ãªã³ã°åç §ã®çæãææ¢ãããã³ã°ãªã³ã°åç §ã®åºçŸæ©äŒãæžå°ããããã®ã§ãã
ãŸãããã®ææ¡ã«ããæé»/æ瀺çå®æ°åæåã¯å®æ°åæåãã®ãã®ã¯æ¢åã®ä»çµã¿ã䜿çšããŸããããªãã¡ãã¯ã©ã¹åã®æ§ç¯ã«äœ¿çšãããã³ã³ã¹ãã©ã¯ã¿ãconstexpr
ã³ã³ã¹ãã©ã¯ã¿ã§ããïŒãã€ããã®ã¡ã³ãããã¹ãŠå®æ°åŒã§åæåããïŒå Žåã¯ãã®ææ¡ã®æ©æµãåããããããã«ãªããŸããããã¯ããªãã¡constexpr
ã®å©ç¹ãšããŠå®å
šæ§ã®åäžãå ããããã«ãªããã¯ã©ã¹ã®åæåãããã«äŒŽãåŠçãconstexpr
察å¿ãããŠããããšã®éèŠæ§ãé«ãŸãããšã«ãªããŸãã
std::integral_constant
ã®å€ãçæãããŠãŒã¶ãŒå®çŸ©ãªãã©ã«ã®ææ¡ã
以åã®èšäºãåç §
ãã®ãªããžã§ã³ã§ã®å€æŽã¯
- äºé²ãªãã©ã«ããªãã£ãã¯ã¹
0B
ã®èŠèœãšãã®ä¿®æ£ integral_constant
ã«åé-
ãè¿œå ããããšãšãT
ãžã®æé»å€æã®çžäºäœçšã«ã€ããŠã®è°è«ãè¿œèš
ãªã©ã§ãã
ãã®ææ¡ã¯ãconstexpr_t
ãšããããå
ç¢ãªå®æ°åãè¿œå ããŠãããã«å¯ŸããŠãŠãŒã¶ãŒå®çŸ©ãªãã©ã«ãæäŸããæ¹åïŒP2725R0ïŒã奜ãŸããããããã¡ããšçµ±åãããå¥ã®ææ¡ïŒP2781ïŒã«äœæ¥ãåŒãç¶ãããŸãã
æšæºã©ã€ãã©ãªã«ãŠãã³ãŒãæååã®çžäºå€æãµããŒããè¿œå ããææ¡ã
ãŠãã³ãŒãã¯æåã³ãŒãã®èŠæ ŒãšããŠããã¡ã¯ãã¹ã¿ã³ããŒããšãªã£ãŠãããæ¥åžžçã«ãœãããŠã§ã¢ã䜿çšããéåžžã«å€ãã®ãŠãŒã¶ãŒã«ãšã£ãŠéèŠãªãã®ã§ããããããC/C++ã¯æ¬è³ªçã«ãŠãã³ãŒãããµããŒãããŠããªãæ°å°ãªãäž»èŠãªããã°ã©ãã³ã°èšèªãšãªã£ãŠããŸãã
ãã®ææ¡ã¯ãã®ç¶æ³ã®ä¿®æ£ã®ããã«ããŸãUTFïŒãŠãã³ãŒãã«ãããæåè¡šçŸïŒã®çžäºå€ææ©èœãæšæºã©ã€ãã©ãªã«è¿œå ããããšãç®æããã®ã§ãã
ãã®ææ¡ã«ããå€æã€ã³ã¿ãŒãã§ãŒã¹ã¯æ¬¡ã®ãããªèšèšãéžæããŠããŸã
<ranges>
ãšã®èŠªåæ§ãçªå µãé 延ãã¥ãŒã®ãµããŒããªã©- ïŒã¬ã¬ã·ãŒãªïŒã€ãã¬ãŒã¿ã®ãµããŒããä»»æã®ã€ãã¬ãŒã¿åãèæ ®ãã
- ãã€ã³ã¿ã®ãµããŒããSIMDãçšãããããªæéã®å€ææ¹æ³ã¯ãã€ã³ã¿ãä»ããŠè¡ããã
- å€æã¯ãã©ãã¯ããã¯ã¹ã§ã¯ãªããå ¥åæååäžã®ããšã³ã³ãŒãã£ã³ã°ã®åãç®ãå£ãããšã³ã³ãŒãã£ã³ã°åæãªã©ã®ç¶æ ããŠãŒã¶ãŒã調æ»ã§ãããŠãŒãã£ãªãã£ãæäŸãã
- nullçµç«¯ãããæååãç¹å¥æ±ãããªã
- åãããã¹ããç°ãªãã¿ã€ãã³ã°ã§ã³ãŒããŠãããïŒUTFãšã³ã³ãŒãã£ã³ã°ã®1åäœã®æŽæ°å€ïŒãšããŠè¡šç€ºãããå Žåãšã³ãŒããã€ã³ãïŒãŠãã³ãŒã空éäžã®32bitæŽæ°å€ïŒãšããŠè¡šç€ºãããããšãããããããã®ãããå€æã€ãã¬ãŒã¿ã¯å€ææžã¿ã®ã³ãŒããŠãããã®å ã®ããŒã¿ã«ã¢ã¯ã»ã¹ãã簡䟿ãªæ¹æ³ãæäŸããã
ãã®ææ¡ã¯ãããã巚倧ã§ããäž»ã«æ¬¡ã®ãã®ããæ§æãããŠããŸã
- APIãå¶çŽããããã®ã³ã³ã»ãã
- nullçµç«¯ãããæååã®ããã®çªå µå
- UTFã·ãŒã±ã³ã¹ã®ç¶æ ãç §äŒããå®æ°ãšé¢æ°
- å€æã¢ã«ãŽãªãºã
- ã€ãã¬ãŒã¿/Rangeã¢ã«ãŽãªãºã
- å€æã€ãã¬ãŒã¿
- å€æ
view
ãŸãããããã®ãã®ã¯åºæ¬çã«std::uc
åå空éã«å®çŸ©ãããŠããŸã
ææ¡ææžããããµã³ãã«ã³ãŒã
ãããã¡ãããããã¡ãžã®ããã©ãŒãã³ã¹éèŠã®å€æ
// UTF-8 -> UTF-16 ãžå€æãã
// ãããã¡ã®ãµã€ãºãåãã«ããããšã§ãå€æã«äœè£ãããããã«ãã
char utf8_buf[buf_size];
char utf16_buf[buf_size];
char * read_first = utf8_buf;
while (true) {
// UTF-8ã·ãŒã±ã³ã¹ãèªã¿åãïŒãããã¯ãŒã¯ãªã©ïŒ
// æ«å°Ÿã«éšåçãªUTF-8ã·ãŒã±ã³ã¹ãçŸããã
char* buf_last = read_into_utf8_buffer(read_first, utf8_buf + buf_size);
if (buf_last == read_first)
continue;
// æå¹ãªUTF-8ã·ãŒã±ã³ã¹ãç¹å®ããïŒéšåçãªã·ãŒã±ã³ã¹ãé€å€ããïŒ
char* last = buf_last;
auto const last_lead = std::ranges::find_last_if(utf8_buf, buf_last, std::uc::lead_code_unit);
if (!last_lead.empty()) {
auto const dist_from_end = buf_last - last_lead.begin();
assert(dist_from_end <= 4);
if (std::uc::utf8_code_units(*last_lead.begin()) != dist_from_end) {
last = last_lead.begin();
}
}
// std::ranges::copy()ãšåãã€ã³ã¿ãŒãã§ãŒã¹ã§ãå€æããªããã³ããŒãã
auto const result = std::uc::transcode_to_utf16(utf8_buf, last, utf16_buf);
// å€æçµæïŒUTF-16ïŒã䜿ã£ãŠäœããã
send_utf16_somewhere(utf16_buf, result.out);
// æ«å°Ÿã«ãã£ãéšåçãªã·ãŒã±ã³ã¹ã次ã®åŠçãããã¡ã®å
é ãžç§»å
read_first = std::ranges::copy_backward(last, buf_last, utf8_buf).out;
}
ãªããžã§ã¯ãããã®ãªãã¹ãé«éãªå€æ
struct my_string; // ãã€ã³ã¿ã€ã³ã¿ãŒãã§ãŒã¹ãæããªãæååå
// UTF-8æååã®ååŸ
my_string input = get_utf8_input();
// åºåãããã¡
std::vector<uint16_t> input_as_utf16(input.size()); // Reserve some space.
// UTF-16 -> UTF-8 å€æ
auto const result = std::uc::transcode_to_utf16(input, input_as_utf16.data());
input_as_utf16.resize(result.out - input_as_utf16.data()); // Trim unused space.
ãªããžã§ã¯ãããã®ãªãã¹ãç°¡åãªå€æ
struct my_string; // ãã€ã³ã¿ã€ã³ã¿ãŒãã§ãŒã¹ãæããªãæååå
// UTF-8æååã®ååŸ
my_string input = get_utf8_input();
// åºåãããã¡
std::vector<uint16_t> input_as_utf16;
// UTF-16 -> UTF-8 å€æ
std::ranges::copy(input, std::uc::from_utf8_back_inserter(input_as_utf16));
æ¢åã®ã€ãã¬ãŒã¿APIãžã®ã¢ããã
// UTF-16ã·ãŒã±ã³ã¹ãåããé¢æ°ãã³ãã¬ãŒã
template<class UTF16Iter>
void process_input(UTF16Iter first, UTF16Iter last);
// UTF-8æååã®ååŸ
std::string input = get_utf8_input(); // std::stringã«UTF-8æååãè©°ããŠäœ¿çš
// UTF-8 -> UTF-16 å€æãã€ã€ãé¢æ°ã«æž¡ãïŒé
延è©äŸ¡ïŒ
process_input(std::uc::utf_8_to_16_iterator(input.begin(), input.begin(), input.end()),
std::uc::utf_8_to_16_iterator(input.begin(), input.end(), input.end()));
// viewã®å©çšã«ãããããªãç°¡åå
auto const utf16_view = std::uc::as_utf16(input);
process_input(utf16_view.begin(), utf16.end());
æ¢åã®Range APIãžã®ã¢ããã
// UTF-16ã·ãŒã±ã³ã¹ãåããé¢æ°ãã³ãã¬ãŒã
template<class UTF16Range>
void process_input(UTF16Range && r);
// UTF-8æååã®ååŸ
std::string input = get_utf8_input(); // std::stringã«UTF-8æååãè©°ããŠäœ¿çš
// UTF-8 -> UTF-16å€æãã€ã€ãé¢æ°ã«æž¡ãïŒé
延è©äŸ¡ïŒ
process_input(std::uc::as_utf16(input));
ãã®äŸã§ã¯ïŒããããWindowsç°å¢ã§é »åºããïŒUTF-8ããUTF-16ãžã®å€æã®ã¿ãæ±ã£ãŠããŸãããææ¡ãšããŠã¯UTF-8/16/32ã®å šãŠã®çžäºå€æãå«ãã§ããŸãã
ãã®ææ¡ã®æäŸããæ©èœã¯ãBoost.TextãšããŠBoostã«ææ¡äžã®ã©ã€ãã©ãªã®äžéšãšããŠ5幎ã»ã©ã®å®è£ çµéšããããŸãã
æšæºã©ã€ãã©ãªã«ãŠãã³ãŒãæååã®æ£èŠåãµããŒããè¿œå ããææ¡ã
ãã®ææ¡ã¯âã®ææ¡ã«åŒãç¶ããŠããŠãã³ãŒããµããŒãæ¹åã®ããã«ãŠãã³ãŒãæ£èŠåæ©èœãæšæºã©ã€ãã©ãªã«è¿œå ããããšãããã®ã§ãã
ãŠãã³ãŒãã®æ£èŠåãšã¯ãåãæå³ãæã€è€æ°ã®æåïŒã³ãŒããã€ã³ãïŒããã1ã€ã®æåïŒã³ãŒããã€ã³ãïŒã«å€æããããšãèšããŸããäŸãã°ãåè§å šè§ããäžžæåãªã©ã察å¿ããéåžžã®æåãžå€æããŸãã
ãã®ææ¡ã«ããæ£èŠåã€ã³ã¿ãŒãã§ãŒã¹ã¯æ¬¡ã®ãããªèšèšãéžæããŠããŸã
<ranges>
ãšã®èŠªåæ§ãçªå µãé 延ãã¥ãŒã®ãµããŒããªã©- ïŒã¬ã¬ã·ãŒãªïŒã€ãã¬ãŒã¿ã®ãµããŒããä»»æã®ã€ãã¬ãŒã¿åãèæ ®ãã
- ãã€ã³ã¿ã®ãµããŒããSIMDãçšãããããªæéã®å€ææ¹æ³ã¯ãã€ã³ã¿ãä»ããŠè¡ããã
- å€æã¯ãã©ãã¯ããã¯ã¹ã§ã¯ãªããå ¥åæååäžã®ããšã³ã³ãŒãã£ã³ã°ã®åãç®ãå£ãããšã³ã³ãŒãã£ã³ã°åæãªã©ã®ç¶æ ããŠãŒã¶ãŒã調æ»ã§ãããŠãŒãã£ãªãã£ãæäŸãã
- nullçµç«¯ãããæååãç¹å¥æ±ãããªã
- UTFã®åœ¢åŒããšã«æé©ãªã¢ã«ãŽãªãºã ãžã®ãã£ã¹ããã
- ããã©ãŒãã³ã¹ã®ãã
- 䜿çšããUTF圢åŒãå€ãã£ãæã§ããåãã³ãŒããå©çšããããšãã§ããããã«ãã
- ç ©éãªãŠãã³ãŒãã®è©³çŽ°ãé èœãããããé«ã¬ãã«ã®æœè±¡åãæäŸãã
ãã®ææ¡ã¯äž»ã«æ¬¡ã®ãã®ããæ§æãããŠããŸã
- ãŠãã³ãŒãããŒãžã§ã³å®æ°
- ã¹ããªãŒã ã»ãŒããªæäœ
- ã¹ããªãŒã ã»ãŒããªã¢ã«ãŽãªãºã
- ã€ãã¬ãŒã¿/Rangeã¢ã«ãŽãªãºã
- ã¹ããªãŒã ã»ãŒããªã€ãã¬ãŒã¿
- ã¹ããªãŒã ã»ãŒããª
view
- APIãå¶çŽããããã®ã³ã³ã»ãã
- ãµããŒãããæ£èŠå圢åŒã®åæå
- æ±çšã®æ£èŠåã¢ã«ãŽãªãºã
- äžåºŠã«è€æ°ã®åºåãè¡ãã¢ã«ãŽãªãºã
std::string
ã®ããã®æ£èŠåæäœ
ãŸãããããã®ãã®ã¯åºæ¬çã«std::uc
åå空éã«å®çŸ©ãããŠããŸã
ææ¡ææžããããµã³ãã«ã³ãŒã
ã³ãŒããã€ã³ãã®ã·ãŒã±ã³ã¹ãNFCã«æ£èŠåãã
std::string s = /* ... */; // std::stringã«UTF-8æååãè©°ããŠäœ¿çš
// æ£èŠåãããŠããªãããšã確èª
assert(!std::uc::is_normalized(std::uc::as_utf32(s)));
// åºåãããã¡
char * nfc_s = new char[s.size() * 2];
// æ£èŠåã¯ã³ãŒããã€ã³ãã§åäœããããããŸãUTF32ã«å€æããïŒas_utf32()ã«ãã£ãŠïŒå¿
èŠããã
auto out = std::uc::normalize<std::uc::nf::c>(std::uc::as_utf32(s), nfc_s);
// nullçµç«¯
*out = '\0';
// æ£èŠåãããŠããããšã確èª
assert(std::uc::is_normalized(nfc_s, out));
string-likeãªã³ã³ãããžåºåãã
std::string s = /* ... */; // std::stringã«UTF-8æååãè©°ããŠäœ¿çš
// æ£èŠåãããŠããªãããšã確èª
assert(!std::uc::is_normalized(std::uc::as_utf32(s)));
// åºåå
std::string nfc_s;
nfc_s.reserve(s.size());
// æ£èŠåã¯ã³ãŒããã€ã³ãã§åäœããããããŸãUTF32ã«å€æããïŒas_utf32()ã«ãã£ãŠïŒå¿
èŠããã
std::uc::normalize_append<std::uc::nf::c>(std::uc::as_utf32(s), nfc_s);
// æ£èŠåãããŠããããšã確èª
assert(std::uc::is_normalized(std::uc::as_utf32(nfc_s)));
ãã®å Žåãnormalize_append()
ã«ãã£ãŠããçšåºŠçºããŠåºåãããããšã§ãããé«éã«ãªãå¯èœæ§ããããŸãã
æ£èŠåãç¶æãããŸãŸæ£èŠåæžã¿æååãæŽæ°ãã
std::string s = /* ... */;// std::stringã«UTF-8æååãè©°ããŠäœ¿çš
// æ£èŠåãããŠããããšã確èª
assert(std::uc::is_normalized(std::uc::as_utf32(s)));
// æ¿å
¥ãããæååïŒæ£èŠåãããŠããªããããããªã
std::string insertion = /* ... */;
// æ£èŠåããªããæ¿å
¥
normalize_insert<std::uc::nf::c>(s, s.begin() + 2, std::uc::as_utf32(insertion));
// æ£èŠåãããŠããããšã確èª
assert(std::uc::is_normalized(std::uc::as_utf32(nfc_s)));
ãã®ææ¡ã®æäŸããæ©èœããŸããBoost.TextãšããŠBoostã«ææ¡äžã®ã©ã€ãã©ãªã®äžéšãšããŠ5幎ã»ã©ã®å®è£ çµéšããããŸãã
ããŒã«ã«ã¹ã³ãŒãã®äžæãªããžã§ã¯ãã®å¯¿åœãæããã¹ã³ãŒããŸã§å»¶é·ããææ¡ã
ãã®ææ¡ã¯ã以åã®P2658ãšP2623ã®ææ¡ãããããŒã«ã«äžæãªããžã§ã¯ãã®å¯¿åœå»¶é·é¢é£ã®éšåãæœåºãããã®ã§ããããããã«ã€ããŠã¯ä»¥åã®èšäºãåç §
- P2623R0 implicit constant initialization - WG21æ次ææ¡ææžãçºããïŒ2022幎07æïŒ
- P2658R0 temporary storage class specifiers - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
ãã ãããã®ææ¡ã§ã¯P2658ã«å«ãŸããŠããvariable_scope
ãªã©ã®æå®ã¯å«ãŸããŠããããP2623ã«å ããŠP2658ã«å«ãŸããŠããvariable_scope
ãšåçã®å¯¿åœå»¶é·ãææ¡ããŠããŸãã
次ã®ãããªé¢æ°ãããã£ããšã
const std::string& f(const std::string& defaultValue) {
return defaultValue;
}
ãã®é¢æ°ã®å
éšããã¯ãåŒæ°ã®defaultValue
ãã©ããã寿åœãæã€ã®ãã¯åãããŸãããããã®åç
§ãæ»ãå€ã§è¿ãããšã«ã¯åé¡ããããŸãããããã¯å¿
ãããããããããšã§ããããŸããã
ãã®f()
ã«äžæãªããžã§ã¯ããæž¡ããŠåŒã³åºããšãæé»çãªã¹ã³ãŒããè¿œå ããã圢ã«ãªããŸãã
int main() {
// å
ã»ã©ã®f()ã®ãã®ãããªåŒã³åºãã¯
{
f("Hello World"s);
}
// ãã®ãããªåŒã³åºããšãªã
{
{
auto anonymous = "Hello World"s;
f(anonymous);
}
}
}
ãã®æãæ»ãå€ãåããŠãããš
int main() {
// å
ã»ã©ã®f()ã®ãã®ãããªåŒã³åºãã¯
{
const std::string& value = f("Hello World"s);
}
// ãã®ãããªåŒã³åºããšãªã
{
const std::string& value; // å®éã«ã¯åæååãå¿
èŠ
{
auto anonymous = "Hello World"s;
value = f(anonymous);
}
}
}
ã³ã³ãã€ã©ã¯éåžžã®C++ãšããŠã¯ãããªãã³ãŒãã«æžãæãããã®ããã«ã³ã³ãã€ã«ããŸããããã«ãã£ãŠãäžæãªããžã§ã¯ãanonymous
ã®ã¹ã³ãŒãã¯ä»ã®å€æ°ãšã¯ç°ãªãããšã«ãªããããã°ã©ãã®æåŸ
ãšãäžèŽããªããªããŸãã
ãã®æãæãèªç¶ãªã®ã¯anonymous
ã®ã¹ã³ãŒããæ»ãå€ãåããŠããvalue
ãšåãã«ãªãããšã§ãããã®å Žåã®value
ã®ã¹ã³ãŒãã®ããšããã®ææ¡ã§ã¯ãããã¯ã¹ã³ãŒããšåŒã³ãé¢æ°åŒã³åºãæã®ãã®ãããªäžæãªããžã§ã¯ãã®å¯¿åœãçŸåšã®æãããããã¯ã¹ã³ãŒããŸã§å»¶é·ããããšãææ¡ããŠããŸãã
ããã«ãã£ãŠãåç §ã»ãã³ãã£ã¯ã¹ãæã€ã¯ã©ã¹ã«ãã£ãŠããããã³ã°ãªã³ã°åç §ãæå¶ãããŸãã
int main() {
std::string_view sv = "Hello World"s;
...
std::cout << sv; // ok
}
ãã ããã®ãããªå Žåã«ã¯ãäžæãªããžã§ã¯ãã®ãããã¯ã¹ã³ãŒããžã®å¯¿åœå»¶é·ãæ©èœããªãå ŽæããããŸã
std::string_view sv = "initial value"s;
if (randomBool()) {
sv = "if value"s;
} else {
sv = "else value"s;
}
ãã®å Žåã"if value"s
ã"else value"s
ã®å¯¿åœã¯if
ç¯ãšelse
ç¯ã®ããããã®ãããã¯ã¹ã³ãŒããŸã§ã¯å»¶é·ããŠããŸãããsv
ã«æçžããããšã«ãã£ãŠãã®å€åŽã«æã¡åºãããŠããŸããšäŸç¶ãšããŠãã³ã°ãªã³ã°åç
§ãšãªããŸãã
ãã®å Žåã«ããããã®äžæãªããžã§ã¯ããå€æ°sv
ãšåãã¹ã³ãŒããæã£ãŠããã°ãã®åé¡ã¯è§£æ±ºãããŸãããã®ææ¡ã§ã¯ãã®ãããªã¹ã³ãŒãã®ããšãå€æ°ã¹ã³ãŒãïŒvariable scopeïŒãšåŒã³ãäžæãªããžã§ã¯ããçŽæ¥å¥ã®å€æ°ã«ä»£å
¥ãããå Žåã«ãã®å¯¿åœã代å
¥å
ã®å€å€æ°ã¹ã³ãŒããŸã§å»¶é·ããããšãææ¡ããŠããŸãã
ããã«ãã£ãŠãé¢æ°å éšã§çºçãããçŽæ¥çãªãã³ã°ãªã³ã°åç §ã®çºçãæå¶ããŸãã
çµå±ããã®ææ¡ã¯æ¬¡ã®2ã€ã®ããšãææ¡ããŸã
- ããŒã«ã«å€æ°ã®äžæå€æ°ã¯å€æ°ã¹ã³ãŒããååŸãã
- é¢æ°åŒæ°ã®äžæå€æ°ã¯ãããã¯ã¹ã³ãŒããååŸãã
ãããšåçãªããšã¯ãäŸãã°Cã®è€åãªãã©ã«ã«èŠãããšãã§ããŸãããC++ã«ãããŠãconst auto&
ãauto&&
ã«ããäžæãªããžã§ã¯ã寿åœå»¶é·æã«è¡ãããŠãããããå®è£
ã«ããã£ãŠå€§ããªåé¡ãããããã§ã¯ãªããšæãããŸãã
2022幎11æ7-12æ¥ã«ãã¯ã€ã®Konaã§è¡ããããWG21å šäœäŒè°ã®è°äºé²ã
N4933ãšã®éãã¯ããåãããŸããã
std::format()
ã®ãã©ãŒãããæååå
ã®çœ®æãã£ãŒã«ãã空ã§ããå Žåã«ãããŒã¹ãè¡ããªããŠãããããææ¡ã
ãã©ãŒãããæååå
ã®çœ®æãã£ãŒã«ã{}
ã«ã¯{:+3}
ãªã©ã®ããã«åºåã調æŽããããã®ãªãã·ã§ã³ïŒãã©ãŒãããåŒæ°ïŒãæå®ããããšãã§ããŸãããã®è§£æã®ããã«ã¯std::formatter<T>::parse()
ã䜿çšããããŠãŒã¶ãŒå®çŸ©åã«å¯Ÿãããã©ãŒãããã®ã«ã¹ã¿ãã€ãºã§ã¯ãã®é¢æ°ã§ãªãªãžãã«ãªãã·ã§ã³ãããŒã¹ããããšã§èªäœã®åã«ãªãªãžãã«ã®ãªãã·ã§ã³ãæå®ããŠãã©ãŒãããããããšãã§ããããã«ãªããŸãã
ãšã¯ãããå€ãã®å Žåã¯ãªãã·ã§ã³ç¡ãã®{}
ã®ãŸãŸäœ¿çšãããããšãå€ãããã§ããã®å Žåã«ãçŸåšã®èŠå®ã¯ãã©ãŒãããåŒæ°ã®æç¡ã«ãããããstd::formatter<T>::parse()
ãåŒã³åºãããšãèŠæ±ããŠããŸãã
struct S {};
// âã®Sãstd::format()å¯èœã«ãã
template <>
struct std::formatter<S> {
auto parse(format_parse_context& ctx) { return ctx.begin(); }
auto format(S, format_context& ctx) const { return ctx.out(); }
};
int main() {
auto s1 = fmt::format("{}", S()); // (1) ãã©ãŒãããåŒæ°æå®ãªã
auto s2 = fmt::format("{:}", S()); // (2) ãã©ãŒãããåŒæ°ã¯ç©º
}
(1)ãš(2)ã®äŸã¯ãããããã©ãŒãããåŒæ°ã¯ååšããŠããªããããparse()
ãåŒã³åºãæå³ããããŸããã{fmt}
ã©ã€ãã©ãªã§ã®å®è£
çµéšã«ããã°ããã®ãªãŒããŒãããã¯å®éã«range
ã®ãã©ãŒãããã«ãããŠæªåœ±é¿ãäžããŠããããšã確èªã§ããããã§ããããã¯ãã©ãŒãããæååã®ã³ã³ãã€ã«ææ€æ»çãparse()
ãåŒã³åºãå¿
èŠã®ããä»ã®ã³ã³ããã¹ãã«ãããŠãåæ§ã§ããå¯èœæ§ããããŸãã
ãŸããC++23ã®range
ã§ã¯ãã©ãŒããããªãã·ã§ã³äžã§:...
ã®ããã«ããŠèŠçŽ åã«å¯Ÿãããªãã·ã§ã³æå®ãè¡ãããšãã§ããããã§ãåæ§ã®åé¡ãçºçããŸãã
int main() {
auto s3 = std::format("{}", std::vector<S>(2)); // vector : ãªããS : ãªã
auto s4 = std::format("{:}", std::vector<S>(2)); // vector : 空ã S : ãªã
auto s5 = std::format("{::}", std::vector<S>(2)); // vector : 空ã S : 空
// ^ èŠçŽ åSã«å¯Ÿãã空ã®ãã©ãŒãããåŒæ°æå®
}
ããã¯ãããã®ã±ãŒã¹ã§ããå€åŽã®std::vector
ãšèŠçŽ åã®S
ã«å¯ŸããŠãã©ãŒããããªãã·ã§ã³ãæå®ããŠããŸãããçŸåšã®èŠå®ã§ã¯ãã©ãŒããããªãã·ã§ã³ã®æå®ãªããšç©ºã¯åºå¥ãããŠããããã§ãããrange
ã®èŠçŽ åã«å¯Ÿãããã©ãŒããããªãã·ã§ã³æå®ã«ãããŠã¯ããŒã¹ã®éœåäžïŒã»ãŒ:
ã®æç¡ã ãã§èŠçŽ åã«å¯Ÿãããã©ãŒããããªãã·ã§ã³æç¡ã決ãŸãã®ã§ïŒãã®2ã€ã®éããåºå¥ããããšãã§ããŸããããã®ããããã®ææ¡ã§ã¯ãã®2ã€ã®ã±ãŒã¹ã¯åçã«æ±ãããããã«ãªããŸãã
ãã®åé¡ã¯LWG Issue 3776ã§ææããããã®è§£æ±ºã®ããã«ã¯ææ¡ãå¿ èŠã«ãªããšããããšã§ããã®ææ¡ãæžãããŸããããã®ä¿®æ£ã¯ãçç¥ããããšãèš±å¯ãããã®ã®å¿ é ã§ã¯ãªãããšãªãããã«ãªã£ãŠããŸãã
ãŸããé¡äŒŒã®åé¡ã®è§£æ±ºãšããŠãstd::tuple
ã«å¯Ÿãããã©ãŒãããæã«èŠçŽ åã«å¯Ÿãããããã°åºåãæå¹åã§ããŠããªãã£ããã°ã®ä¿®æ£ãåæã«è¡ãããŸãã
std::tuple
ã«å¯Ÿãããã©ãŒãããã§ã¯èŠçŽ åã«å¯Ÿãããªãã·ã§ã³æå®ãç¡ããããèŠçŽ åã«å¯Ÿãããªãã·ã§ã³ã®parse()
ã¯åžžã«çç¥ãããŠããŸãããäžæ¹ã§ãèŠçŽ åã®æå/æåååã«å¯ŸããŠãããã°åºåãªãã·ã§ã³ïŒ?
ïŒãåžžã«æå¹ã«ãªã£ãŠããããã®ããã«èŠçŽ åã®ãã©ãŒããããªãã·ã§ã³ã®parse()
ã§std::formatter::set_debug_format()
ã®åŒã³åºããå¿
èŠã«ãªãããšããããçš®ã®ççŸç¶æ
ã«é¥ã£ãŠããŸããïŒæ¬æ¥ãset_debug_format()
ã¯parse()
å
�
ãªãã·ã§ã³ãããŒã¹ãããšãã«åŒã³åºãããããšã§ãããã°åºåãæå¹åããŸãïŒã
ãã®ææ¡ã§ã¯ããã解決ããstd::tuple
ã«å¯Ÿãããã©ãŒãããã§ã¯ãã¹ãããèŠçŽ åã§ãããã°åºåãå¯èœãªå Žåã«set_debug_format()
ãæ£ããåŒã¶ããã«èŠå®ãä¿®æ£ããŸãã
auto s = fmt::format("{}", std::make_tuple(std::make_tuple('a')));
// Before : ((a))
// Aftter : (('a'))
std::format()
- cpprefjpstd::formatter::set_debug_format()
- cpprefjp- LWG Issue 3776. Avoid parsing format-spec if it is not present or empty
- P2733 é²è¡ç¶æ³
2022幎ã«è¿œå ãããæ°ããSIæ¥é èŸã«å¯Ÿå¿ããstd::ratio
ç¹æ®åãè¿œå ããææ¡ã
<ratio>
ãããã«ã¯ã³ã³ãã€ã«ææçæ°åstd::ratio
ãšãSIæ¥é èŸïŒããªãšããã€ã¯ãããããã®ã¬ãªã©ïŒã«å¯Ÿå¿ãããã®äºåå®çŸ©åãšã€ãªã¢ã¹ãå®çŸ©ãããŠããŸãã
SIæ¥é èŸã¯é·ããæŽæ°ãããŠããŸããã§ãããã2022幎ã«æ°ãã次ã®4ã€ãè¿œå ãããŸãã
-
quecto :
$10^{-30}$ -
ronto :
$10^{-27}$ -
ronna :
$10^{27}$ -
quetta :
$10^{30}$
ãã®ææ¡ã¯ããã®4ã€ã«å¯Ÿå¿ããèšå®æžã¿ã®std::ratio
ãšã€ãªã¢ã¹ãè¿œå ãããã®ã§ããååã¯SIæ¥é èŸåãšåãã§ææ¡ãããŠããŸãã
ãã ããæ¢åã®std::yocto
ãstd::yotta
çãšåæ§ã«ãitmax_t
åã§å€ãè¡šçŸå¯èœãªå ŽåïŒ64bitãè¶
ããå¹
ã®æŽæ°åãæäŸããŠããªãå ŽåïŒã¯å®çŸ©ããªããŠãããããã«ãããŠããŸãã
- SIæ¥é èªè¿œå ïŒèšéæšæºç·åã»ã³ã¿ãŒïŒNMIJïŒ
- SIæ¥é èŸ - cpprefjp
<ratio>
- cpprefjp- P2734 é²è¡ç¶æ³
ISO 10646ïŒUCSïŒã®ä»£ããã«ãŠãã³ãŒãæšæºãåç §ããããã«ããææ¡ã
çŸåšã®C++ã¯ãŠãã³ãŒãã®ãµããŒãã®ããã«ãŠãã³ãŒãæšæºãšISO 10646ã®äž¡æ¹ãåç §ããŠããŸãããã®2ã€ã¯ã»ãšãã©åãå 容ã§ã¯ãããã®ã®å¥ã ã®èŠæ Œã§ãã
ãŠãã³ãŒãæšæºã¯åã«æåã³ãŒããå®ããã ãã§ãªããæ£èŠåãæ¯èŒã倧æåãšå°æåã®å€æãªã©ããŠãã³ãŒãæåãæ±ãããã®ã¢ã«ãŽãªãºã ãå«ãã§ãããªã©ãISO 10646ã«æ¯ã¹ãŠããåºãèŠæ Œã«ãªã£ãŠããŸãããŸãããŠãã³ãŒãæšæºã®å®ãæäŸãããããã®ãã®ã¯ãåç §ãããŠãã³ãŒãæšæºã®ããŒãžã§ã³ãå³å¯ã«æå®ããŠãããããç°ãªãããŒãžã§ã³ã§ã¯åäœãä¿èšŒãããŸããããISO 10646ãšãŠãã³ãŒãã®ãªãªãŒã¹ãµã€ã¯ã«ãç°ãªãããšãããããå³å¯ã«äžèŽãããããšãå°é£ã«ãªããŸãã
ãŸããISO 10646ãšãŠãã³ãŒãæšæºã§ã¯äœ¿çšããçšèªã«ã埮åŠã«å·®ç°ãããããã®éãã圱é¿ã«ã€ããŠè©äŸ¡ããããã«SG19ïŒãŠãã³ãŒãã«é¢ããäœæ¥éšäŒïŒã®æéãç¡é§ã«æ¶è²»ããŠããŸããããã«ããŠãã³ãŒãæšæºã¯é¢é£ãããŠãã³ãŒãããŒã¿ãããŒã«ã«äœ¿çšãããããããªãã©ãŒãããã§æäŸããŠããŸãããISO 10646ã¯ãã ã®PDFã§ãããå®è£ è ã«ãšã£ãŠãISO 10646察å¿ã®æ€èšŒãªã©ã¯éè·ã«ãªã£ãŠããŸãã
C++ã§ã¯ãèšèªãšã©ã€ãã©ãªã®äž¡æ¹ã§ãŠãã³ãŒãã®ãµããŒããé²ããŠãããããã§ã¯ãŠãã³ãŒãã®åç §ãå¿ èŠãšãªããŸããä»åŸãããé²ããŠããã«ããã£ãŠISO 10646察å¿ã®ããã«ïŒèŠæ Œåãšå®è£ ã®ïŒæéãæ¶è²»ããã®ãåé¿ããæšæºã®äŸåé¢ä¿ãæžãããŠæšæºãæ確åããããã«ãISO 10646ãžã®åç §ãå®å šã«ãŠãã³ãŒããžã®åç §ã§çœ®ãæããããšããææ¡ã§ãã
ãã®ææ¡ã¯æšæºã®ææžããISO 10646ã®åç §ãåé€ããããã«é¢é£ããæèšããŠãã³ãŒãæšæºãåç §ããããã«æžãæããã ãã®ãã®ãªã®ã§ãå®è£ ã«ã¯åœ±é¿ã¯ãããŸããã
ãã ã__STDC_ISO_10646__
ãšããäºåå®çŸ©ãã¯ãã ãã¯åœ±é¿ãåããŸãããããã«ã€ããŠã¯ãŠãã³ãŒãã®ä»»æã®ã³ãŒããã€ã³ãå€ãwchar_t
ãªããžã§ã¯ããæ ŒçŽã§ããããšã®ãããªå®çŸ©ã«ãïŒå®è³ªçŸåšãšå€æŽã¯ãªãïŒããã®å€ãå®è£
å®çŸ©ãšããããšã§ISO 10646ãžã®åç
§ãåé¿ããããã«ããŠããŸãã
- ISO/IEC 10646 - Wikipedia
__STDC_ISO_10646__
| Programming Place Plusãèšèªç·šãæšæºã©ã€ãã©ãªã®ãªãã¡ã¬ã³ã¹- P2736 é²è¡ç¶æ³
æ°ããããŒã¯ãŒãã«ããæ¡ä»¶äžå¿ãªå¥çŽæ§æã®ææ¡ã
çŸåšæ€èšäžã®å¥çŽããã°ã©ãã³ã°ã®ããã®æ§æã¯ãC++20ã§åé€ãããæããå€ãããå±æ§ãå©çšãããã®ãäž»æµã§ãããã ããããã¯ãŸã 確å®ãããã®ã§ã¯ãªããä»ã«ãã¯ããŒãžã£ãæèããæ§æïŒP2461R1ïŒãææ¡ãããŠããŸãã
å±æ§ | ã¯ããŒãžã£ |
---|---|
int select(int i, int j)
[[pre: i >= 0]]
[[pre: j >= 0]]
[[post r: r >= 0]]
{
[[assert: _state >= 0]];
if (_state == 0)
return i;
else
return j;
}
int pre; // OK
int assert; // OK
int post; // OK |
int select(int i, int j)
pre{i >= 0}
pre{j >= 0}
post(r){r >= 0}
{
assert{_state >= 0};
if (_state == 0)
return i;
else
return j;
}
int pre; // OK
int assert; // ???
int post; // OK |
ãã®ææ¡ã§ã¯3ã€ç®ã®åè£ãšããŠãprecond, postcond, incond
ïŒé ã«ãäºåæ¡ä»¶ãäºåŸæ¡ä»¶ãã¢ãµãŒãïŒã®3ã€ã®ããŒã¯ãŒããçšããæ¡ä»¶äžå¿ãªæ§æãææ¡ãããã®ã§ãã
å±æ§ | ãã®ææ¡ |
---|---|
int select(int i, int j)
[[pre: i >= 0]]
[[pre: j >= 0]]
[[post r: r >= 0]]
{
[[assert: _state >= 0]];
if (_state == 0)
return i;
else
return j;
}
int pre; // OK
int assert; // OK
int post; // OK |
int select(int i, int j)
precond(i >= 0)
precond(j >= 0)
postcond(result >= 0)
{
incond(_state >= 0);
if (_state == 0)
return i;
else
return j;
}
int precond; // ERROR
int incond; // ERROR
int postcond; // ERROR |
ãã®ææ¡ã¯P2521R2ã«ããå¥çŽæ©èœã®MVPã«ã€ããŠæ¬¡ã®å€æŽãå ããŸã
- ã¢ãµãŒã·ã§ã³ã®æ§æã
assert
ããincond
ã«å€æŽ precond, postcond, incond
ãå®å šãªïŒæèäŸåã§ã¯ãªãïŒããŒã¯ãŒããšããŠè¿œå- æ¡ä»¶æå®ã¯
()
ã®äžã«åŒãæå®ããprecond(expr), incond(expr), postcond(expr)
- äºåŸæ¡ä»¶ïŒ
postcond
ïŒã§ã¯ãå®çŸ©æžã¿ã®å€æ°result
ã«ãã£ãŠæ»ãå€ãåç §ããå€æ°ãæé»çã«å°å ¥ããã
incond
ã¯äºåæ¡ä»¶ïŒåŠçã®åã«æºããã¹ãæ¡ä»¶ïŒãšäºåŸæ¡ä»¶ïŒåŠçã®åŸã§æºããã¹ãæ¡ä»¶ïŒããã®é¡æšã§ãåŠçã®éäžã§æºããã¹ãæ¡ä»¶ãè¡šãé èªã§ããããã¯ã2åæšã®æ¢çŽ¢é åºãè¡šã3ã€ã®åèªpreorder, inorder, postorder
ãåèã«ããŠäœãããèšèã§ããããŸãã
ã¢ãµãŒã·ã§ã³ïŒassert
ïŒã眮ãæãããåæ©ã¯æ¬¡ã®ãããªãã®ã§ã
- assertionã¯ä»ã®2ã€ïŒpreconditionãpostconditionïŒãšäžè²«ããŠããªã
- æ¡ä»¶ã¯æºãããªãããšãéåãããšèšãããã¢ãµãŒã·ã§ã³ã¯å€±æãããšèšããã
- 3ã€ã®äºæã®äºãã®é¢é£æ§ãæ確ã§ããããšãéèŠ
- æ¢åã®ã¢ãµãŒã·ã§ã³ãšã®æ··å
- C assertïŒ
assert()
ãã¯ãïŒãšstatic_assert
ã«å ããŠãã¢ãµãŒã·ã§ã³ã®ããã®ã©ã€ãã©ãªãå€æ°ååšãã - åã«ã¢ãµãŒã·ã§ã³ãšèšã£ãæã«ã©ããæããŠããããææ§
- C assertïŒ
assert
ã¯ããŒã¯ãŒããšããŠç»é²ã§ããªã- å°ãªããšãC assertãšç«¶åãã
incond
ãšããã¯ãŒãã¯ãã®3ã€ã®ãããã®åé¡ãã¯ãªã¢ããŠããæ°ããé èªã§ãã
ãã®æ°ããããŒã¯ãŒãã¯ACTCD19ãšããC/C++ã³ãŒãããŒã¹èª¿æ»ã§1000件çšåºŠãããããããªãããæ°ããããŒã¯ãŒããšããŠäœ¿çšã§ããããšäž»åŒµããŠããŸãïŒäœ¿ããæ¹ã«ããããŸãã1000件ã¯å€ãã®ã§ã¯ãšæããªãã§ããªãã§ããïŒã
- P2461R0 Closure-based Syntax for Contracts - C++WG21æ次ææ¡ææžãçºããïŒ2021幎10æïŒ
- P2487R0 Attribute-like syntax for contract annotations - C++WG21æ次ææ¡ææžãçºããïŒ2021幎11æïŒ
- P2521R2 Contract support - Working Paper - C++WG21æ次ææ¡ææžãçºããïŒ2022幎03æïŒ
- äºåæšã®pre-order, in-order, post-orderã®ç°¡åã§ãããããã説æ - CTOãç®æãæ¥èš
- P2737 é²è¡ç¶æ³
å®æ°åŒã«ãããŠãvoid*
ãããã€ã³ã¿åãžã®å€æãèš±å¯ããææ¡ã
èæ¯ãã¢ãããŒã·ã§ã³ã¯åŸã®æ¹ã®P2747R0ãšå ±éããã®ã§ãã¡ããã芧ãã ããã
ãã®ææ¡ã§ã¯äž»ã«ãstd::format
ã®constexpr
察å¿ã®ããã«ãåæ¶å»ãŠãŒãã£ãªãã£ãã³ã³ãã€ã«æã«äœ¿çšå¯èœãšããããšãç®çãšããŠããŸãã
#include <string_view>
struct Sheep {
constexpr std::string_view speak() const noexcept { return "Baaaaaa"; }
};
struct Cow {
constexpr std::string_view speak() const noexcept { return "Mooo"; }
};
// åæ¶å»ãŠãŒãã£ãªãã£ã®å®è£
äŸ
// speak()ã¡ã³ãé¢æ°ããã€ä»»æã®åã®viewãšãªã
class Animal_View {
private:
// ãªããžã§ã¯ãã®åãæ¶å»ããŠä¿æãããã€ã³ã¿
const void *animal;
// é¢æ°ãã€ã³ã¿
std::string_view (*speak_function)(const void *);
public:
template <typename Animal>
constexpr Animal_View(const Animal &a)
: animal{&a} // ãªããžã§ã¯ããã€ã³ã¿ãvoid*ãžãã£ã¹ããä¿åïŒããã¯å®æ°åŒã§è¡ããïŒ
, speak_function{[](const void *object) {
// å®éã«æž¡ãããAnimalåãã©ã ãåŒå
ã«ä¿åããã©ã ãåŒã¯é¢æ°ãã€ã³ã¿ãžå€æããŠä¿å
// å®éã®åæ
å ±ãçšããŠvoid*ããAnimal*ã埩垰ããã®ã§ãåžžã«æ£ãããã£ã¹ã
return static_cast<const Animal *>(object)->speak(); // ãããã³ã³ãã€ã«æã«å®è¡ã§ããªã
}} {}
constexpr std::string_view speak() const noexcept {
// ãã®ã¯ã©ã¹ãæ£ããæ§ç¯ãããŠããã°ããã®åŒã³åºãã¯åžžã«æ£ããå
ã®ãªããžã§ã¯ããvoid*ãã埩垰ãããŠspeak()ã¡ã³ããåŒã³åºã
return speak_function(animal);
}
};
// Animal_Viewã®èŠæ±ããã€ã³ã¿ãŒãã§ãŒã¹ãæã€ä»»æã®åã®ãªããžã§ã¯ããæž¡ãããšãã§ãã
std::string_view do_speak(Animal_View av) { return av.speak(); }
int main() {
constexpr Cow cow;
// cannot be constexpr because of static_cast
[[maybe_unused]] auto result = do_speak(cow);
return static_cast<int>(result.size());
}
ãã®ãããªåæ¶å»ãŠãŒãã£ãªãã£ããã£ãŠããããšã¯ãã»ãšãã©ä»®æ³é¢æ°ã«ããããªã¢ã«ãã£ãºã ãšåæ§ã§ãããã®å€§ããªéãã¯ãèŠæ±ããã€ã³ã¿ãŒãã§ãŒã¹ã«æºæ ããã¯ã©ã¹ã¯å¿ ãããããã«ã¢ãããããããã®äœæ¥ãããå¿ èŠããªãïŒéäŸµå ¥çã§ããïŒãåå¥ã®ã¯ã©ã¹ããšã«ä»®æ³é¢æ°ããŒãã«ãå¿ èŠãšããªãããšã«ãããŸãããããŠããã®ãããªåæ¶å»ã¯ããã³ãã¬ãŒãã®ã€ã³ã¹ã¿ã³ã¹åãæå¶ãã³ã³ãã€ã«æéãåæžãããªã©ã®ã¡ãªããããããŸãã
ãããšåæ§ã®ã¢ãããŒãã¯ãstd::format()
ã®å®è£
ã«ãããŠäœ¿çšãããŠããïŒãã©ãŒããã察象åŒæ°ã®æåååã®ããã«ïŒã»ããstd::function_ref
ã®å®è£
ã«ãããŠã䜿çšãããŸãã
ãã ãããã®äŸãèŠãŠãããããã«ããã®ãããªåæ¶å»ã®èã¯ãªããžã§ã¯ããã€ã³ã¿ãvoid*
ãžèœãšããåŸã§å¿
èŠã«ãªã£ãã¿ã€ãã³ã°ã§void*
ãã埩垰ãããšããã«ãããŸãããvoid*
ãããã€ã³ã¿åãžã®ãã£ã¹ãã¯çŸåšå®æ°åŒã§æ瀺çã«çŠæ¢ãããŠããããããããã®åæ¶å»ãã¯ããã¯ã¯ã³ã³ãã€ã«æã«äœ¿çšå¯èœã§ã¯ãããŸããã
ãã®ææ¡ã¯ããã®å¶éãåãé€ãããšã§ãã®ãããªåæ¶å»ãã³ã³ãã€ã«æã«äœ¿çšå¯èœãšããstd::format()
ãstd::function_ref
ãconstexpr
察å¿ããããã®é害ãåãé€ããã®ã§ãã
ãã ããããã§ææ¡ãããŠããã®ã¯ãvoid* -> T*
ã®å€ææã«ãã®ãã€ã³ã¿ãæ£ããT
ã®ãªããžã§ã¯ããæããŠããå Žåã«ã®ã¿å€æãèš±å¯ããããšã§ããã€ã³ã¿çžäºäºææ§ïŒpointer interconvertibleïŒãå
šãç°ãªããã€ã³ã¿ãžã®å€æãèš±å¯ãããã®ã§ã¯ãããŸããã
çŸåšã®ã»ãšãã©ã®ã³ã³ãã€ã©ã®å®æ°åŒã®å®è£
ã«ãããŠã¯ãæªå®çŸ©åäœæé€ãªã©ã®ããã«ãã€ã³ã¿ãšãããæããªããžã§ã¯ãã®ç¶æ
ããã®å®è¡ã«åœãã£ãŠè¿œè·¡ããŠããŸãããã®ããvoid*
ããã®ãã£ã¹ãæã«ãã®æ£ããã®ãã§ãã¯ãè¡ãããšã¯å¯èœã§ãããææ¡ã§ã¯Clang/GCC/MSVC/EDGã®å®è£
è
ãããã®ææ¡ã®å®è£
ãåé¡ãªãäºã確èªããŠããŸãïŒçè
ã®æ¹ã¯Clangã§å®è£
ããŠç¢ºèªããŠããããã§ãïŒã
C++ã®å®å šæ§åäžã®ããã®è¡åãåŒã³ãããææžã
2022幎11æããã«åºãããNSAïŒã¢ã¡ãªã«åœå®¶å®å šä¿éå±ïŒã®ã¬ããŒãïŒSoftware Memory Safety - Department of DefenseïŒã«ãããŠãC++ã¯Cãšãšãã«ã¡ã¢ãªå®å šãªèšèªã§ã¯ãªãä»ã®ã¡ã¢ãªå®å šãªèšèªã«ç§»è¡ããããšãæãŸããããšåæããããŸããããã®ææžã¯ãããåããŠãçè ã®æ¹ïŒBjarne Stroustrupå çïŒã®ãããŸã§åã³ããããã®C++ã®å®å šæ§åäžã®ããã®åãçµã¿ã説æããC++æšæºåå§å¡äŒãšããŠãè¡åããŠããããšãä¿ããã®ã§ãã
åãçµã¿ãšããŠã¯ã³ã¢ã¬ã€ãã©ã€ã³ã®æŽåããããããŒã¹ãšããéç解æããŒã«ã®æŽåãã³ã¢ã¬ã€ãã©ã€ã³åºæºã®éç解æã¢ãããŒã·ã§ã³ã®ææ¡ïŒP2687R0ïŒãªã©ãæããããŠããŸãã
NSAã®ææžã¯å®å šãã¡ã¢ãªå®å šæ§ã«éå®ããŠããŸããå®å šæ§ãšã¯ããã ãã§ã¯ãªããå®å šæ§ãå®çŸããããã®æ¹æ³ãäžéãã§ã¯ãããŸããããŸããå®å šæ§ã¯éèŠã§ã¯ãããŸãã誰ããå®å šæ§ã ããéèŠããããã§ã¯ãªããå®å šæ§ãããä»ã®äºé ïŒäŸãã°ããã©ãŒãã³ã¹ïŒãéèŠãããå ŽåããããŸãããŸããã¢ãã³ãªã³ãŒãã ããå®å šã«ãããšããŠããçŸåšã®å€ãã®C++ã³ãŒãããããªãããã§ã¯ãªãããããã®éå»ã®ã³ãŒãã¯å®å šãªã³ãŒãïŒãããã¯å®å šãªããã°ã©ãã³ã°èšèªïŒããåŒã³åºãããŠäœ¿çšãããŸãã
å®å šæ§ã®åé¡ãæŸçœ®ããã°C++ã®ã³ãã¥ããã£ã®å€§éšåãæãªãããå§å¡äŒã§è¡ãããŠããå€ãã®äœæ¥ãç¡é§ã«ãªã£ãŠããŸããŸãããå®å šæ§ã ããéèŠããããŠãåæ§ã®çµæãæãããšã«ãªããŸãã
ãã®ææžã§ã¯ããŸãå®å šæ§ã®åé¡ãšèããããããšã®ãªã¹ããäœæããP2687R0ã®æ çµã¿ã®äžã§ãããã©ã®ããã«æ¹åã§ããããèããŠããããšãææ¡ããŠããŸããããã¯ãŸããBjarneå çã®ä»åŸã®æ¹éã§ããããŸãã
- Software Memory Safety - Department of Defense
- P2687R0 Design Alternatives for Type-and-Resource Safe C++ - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
- P2739 é²è¡ç¶æ³
é¢æ°ããããŒã«ã«å€æ°ã®åç §ãè¿ããŠããŸãã±ãŒã¹ãã³ã³ãã€ã«ãšã©ãŒã«ããææ¡ã
C++23ã§ã¯ãP2266R3ã®æ¡æã«ãã£ãŠäžéšã®ããŒã«ã«å€æ°ã®åç §ãè¿ãé¢æ°ãã³ã³ãã€ã«ãšã©ãŒãšãªãããã«ãªããŸãã
// åç
§ãè¿ãé¢æ°
int& f(bool b, int i) {
static int s;
if (b) {
return s; // OK
} else {
return i; // error : C++23ãã
}
}
// reference_wrapperãè¿ãé¢æ°
std::reference_wrapper<int> g() {
int w;
return w; // error : C++23ãã
}
ãã®å€æŽã¯ç»æçãªãã®ã§ãããP2266ã®äž»ç®çã¯ãããŸã§æé»ã®ã ãŒã察象ã®æ¡å€§ã«ãã£ãã®ã§ããã¯å¯æ¬¡çãªå¹æã«éãããå®å
šãªãã®ã§ã¯ãããŸãããäŸãã°ãäžèšããããã®å Žåã«ãããŠã®åç
§ã«åœãããã®ãreturn
ã§è¿ãå Žåã¯ããã®åç
§å
ãããŒã«ã«å€æ°ã§ããšã©ãŒã«ãªããŸããã
ãã®ææ¡ã¯ããããããã«é²ãã§ãè¿œå ã§ããã€ãã®å Žåãã³ã³ãã€ã«ãšã©ãŒã«ããããšãããã®ã§ãã
1ã€ç®ã¯åç §ã§ã¯ãªããã€ã³ã¿ãè¿ãé¢æ°ã®å Žåã§ãã
int* h(bool b, int i) {
static int s;
if (b) {
return &s; // OK
} else {
return &i; // error: iã¯æ»ãå€ã®ãã€ã³ã¿ãããå
ã«å¯¿åœãå°œãã
}
}
ïŒããã§ã®errorãšã¯ãšã©ãŒã«ããããšãææ¡ããŠãããšããæå³ã§ã以éãåæ§ã§ãïŒ
ãããšåæ§ã®ããšã¯ãé¢æ°ã®æ¬äœå ã§ãèµ·ããåŸãŸãã
void h(bool b, int i) {
int* p = nullptr;
if (b) {
static int s;
p = &s; // OK
} else {
int i = 0;
p = &i; // error: iã¯æ»ãå€ã®ãã€ã³ã¿ãããå
ã«å¯¿åœãå°œãã
}
// ...
}
ãã®ããã«ããã®ææ¡ã§ã¯æ¬¡ã®ãããªã«ãŒã«ãææ¡ããŠããŸã
ãã€ã³ã¿ãŸãã¯åç §ã®å¯¿åœãå°œããåã«ãã®åç §ãããªããžã§ã¯ãã®å¯¿åœãå°œããå Žåããªããžã§ã¯ãã®ã¢ãã¬ã¹ããã€ã³ã¿ãŸãã¯åç §ã«ä»£å ¥ã§ããªã
ãã ãããã¯ãäžæ®µéã®éæ¥åã ãã察象ãšããŠããŸããã€ãŸãããã§ã«äœããåç
§ããŠããåç
§/ãã€ã³ã¿ãæ°ããåç
§/ãã€ã³ã¿ã«ä»£å
¥ããïŒreturn
ããïŒãããªå Žåã¯ãã®ã«ãŒã«ã«è©²åœããŸããããããããããšãããšãã³ã³ãã€ã©ã¯ããŒã«ã«å€æ°ãšåç
§/ãã€ã³ã¿ã®äŸåé¢ä¿ã°ã©ããäœæããããšã«ãªããããã¯ã³ã³ãã€ã«æéå¢å€§ãšå®è£
ã®è€éåãæããŸãã
次ã«ãã©ã ãåŒãã³ã«ãŒãã³ãããŒã«ã«å€æ°ãåç §ãã£ããã£ããŠããŠããããå å ãããªããžã§ã¯ããè¿ãå Žåãã³ã³ãã€ã«ãšã©ãŒãšããŸãã
auto lambda() {
int i = 0;
return [&i]() -> &int
{
return i;
}; // error: iã¯æ»ãå€ã®ã©ã ããããå
ã«å¯¿åœãå°œãã
}
auto coroutine() {
int i = 0;
return [&i]() -> generator<int>
{
co_return i;
}; // error: instance `i` dies before the returned coroutine
}
ãã®ããã«ããã®ææ¡ã§ã¯æ¬¡ã®ãããªã«ãŒã«ãææ¡ããŠããŸã
ããŒã«ã«å€æ°ãžã®ãã€ã³ã¿/åç §ããã£ããã£ããã©ã ãåŒãŸãã¯ã³ã«ãŒãã³ãé¢æ°ããè¿ãããšã¯ã§ããªã
ããã¯åé ã®ææ¡ããäžæ®µéã ãé²ãã éæ¥åã®äžã§ãèšèªæ©èœã«ããç¹æ®ãªã±ãŒã¹ãåŠçãããã®ã§ãããã以äžã®éæ¥åãåŠçããããšããããšã¯ãåé ãšåæ§ã®çç±ã«ããææ¡ããŠããŸããã
ã³ã³ãã€ã©ã¯ãé¢æ°ãæ»ãå€ãšããŠãªããžã§ã¯ããè¿ãã®ããã®åç §ïŒãã€ã³ã¿ïŒãè¿ãã®ããç¥ã£ãŠããŠããã®é¢æ°å ã§ã®ããŒã«ã«å€æ°ãšãããåç §ããïŒäžæ®µéã®ïŒãã€ã³ã¿ãåç §ãèªèããŠããŸããäºæ®µé以äžã®éæ¥åãåŠçããããšãããšããŒã«ã«å€æ°ã®äŸåé¢ä¿ã°ã©ããæ§ç¯ããå¿ èŠãåºãŠããŠããŸããŸãããäžæ®µéã®éæ¥åïŒãšäžéšã®ç¹æ®ã±ãŒã¹ïŒã ããªãå šãŠã®ã³ã³ãã€ã©ãç°¡åã«æ€èšŒã§ããã¯ãã§ãã
ãã®ææ¡ã«ãã£ãŠãè¿œå ã®éç解æããŒã«ãå¿ èŠãšããããšãªãC++ã®èšèªå ã§å€ãã®ãã³ã°ãªã³ã°åç §ãé²æ¢ã§ããããã«ãªããŸããå®å šãªãã®ã§ã¯ãããŸãããããã®ä¿®æ£ã¯å€§ããªæ¹åã§ãããŸããCã³ãŒããïŒãã®ææ¡ãå®è£ ããïŒC++ãšããŠã³ã³ãã€ã«ããããšã§ãCã®ãã€ã³ã¿ã®å®å šæ§ãæ€èšŒããããšãã§ãããªã©ãC/C++ãšã³ã·ã¹ãã å šäœã®æ¹åã«è²¢ç®ããããšãã§ããŸãã
static_assert
ã®èšºæã¡ãã»ãŒãžïŒç¬¬äºåŒæ°ïŒã«ãã³ã³ãã€ã«æã«çæããæååãæå®ã§ããããã«ããææ¡ã
static_assert
ã®èšºæã¡ãã»ãŒãžã«ã¯çŸåšæååãªãã©ã«ãçŽæ¥æå®ããããšããã§ãããå®æ°åŒã§çæããä»»æã®æååãæå®ããããšãã§ããŸãããããã«ãã£ãŠãã³ã³ãã€ã«æã®èšºæã¡ãã»ãŒãžã®æè»ããæãªãããŠããŸãã
ãã®ææ¡ã¯ãstatic_assert
ã®èšºæã¡ãã»ãŒãžãšããŠå®æ°åŒã§çæãããæååãæå®ããŠãšã©ãŒã¡ãã»ãŒãžãšããŠåºåå¯èœãšããããšã§ãstatic_assert
ã«ããã³ã³ãã€ã«æã®ãšã©ãŒå ±åãæ¹åããããšãããã®ã§ãã
ãã®ææ¡ãéãã°ãå°æ¥çã«std::format()
ã䜿çšå¯èœãšãªãã§ãããã
static_assert(sizeof(S) == 1, std::format("Unexpected sizeof: expected 1, got {}", sizeof(S)));
ãã ãããã®ææ¡ã§ã¯static_assert
ã®èšºæã¡ãã»ãŒãžã«æå®å¯èœãªãã®ãåºããããšãã ãã念é ã«çœ®ããŠããŠãstd::format()
ã®constexpr
察å¿ã«ã€ããŠã¯ææ¡ããŠããŸããã
ãŸãããã®ææ¡ã«ãã£ãŠæå®å¯èœã«ãªãæååãšã¯std::string
ãæãã®ã§ã¯ãªãã次ã®ãããªç¹æ§ãæã€åã®å€ãæååãšèŠåããŠåºåå¯èœãšããããšãææ¡ããŠããŸãã
.size()
ã¡ã³ãé¢æ°ãæã€- æ»ãå€åã¯æŽæ°å
.data()
ã¡ã³ãé¢æ°ãæã€- æ»ãå€åã¯
char*
ãchar8_t*
ã®ã©ã¡ããïŒCV修食ã¯ãã£ãŠãããïŒ
- æ»ãå€åã¯
- 蚺æã¡ãã»ãŒãžã«æå®ããããªããžã§ã¯ãã
msg
ãšãããšã[msg.data(), msg.data() + msg.size())
ã¯æå¹ãªç¯å²ã§ããããš
std::string
ã ãã§ãªããstd::string_view
ãstd::vector<char>
ãªã©ã䜿çšå¯èœã§ãã
æ»ãå€ã®åç §ããã€ã³ã¿ã®æå¹æéãå¥ã®å€æ°ã®çåæéã«äŸåããŠããããšãè¡šæããå±æ§ã®ææ¡ã
ãã®ææ¡ã¯ãé¢æ°ã®æ»ãå€ã§çºçãããã³ã°ãªã³ã°åç §ã®é²æ¢ã»åæžãç®çãšããŠãããäžã®æ¹ã§åºãŠããP2724R0ãP2730ROãP2740R0ãšãã䌌ãç®çã§åãäœè ã«ããææ¡ã§ãã
ãã®ææ¡ã§ã¯ãparameter_dependency
ãšããæ°ããå±æ§ãææ¡ããŠããŠãããã¯dependent
åŒæ°ãšããŠæååã§ãã®æå¹æéãä»ã«äŸåããŠãããã®ãæå®ããproviders
åŒæ°ã«æååã§äŸåå
ã®ãã®ãæå®ããŸãã"return"
ã§æ»ãå€ãæå®ããããšãã§ããã»ããäŸåå
ãšããŠ"this"
ã§*this
ãªããžã§ã¯ããæå®ã§ããŸãã
[[parameter_dependency(dependent{"return"}, providers{"this", "left", "right", "first", "second", "last"})]]
providers
åŒæ°ã¯æååã®é
åã§ãdependent
1ã€ã«ã€ãè€æ°ã®äŸåå
ãæå®ã§ããŸãã
parameter_dependency
å±æ§ã¯é¢æ°ïŒããªãŒé¢æ°åã³ã¡ã³ãé¢æ°ïŒã«æå®ãããã®ã§ãããã«ãã£ãŠdependent
ã«æå®ãããã®ã®æå¹æéãproviders
ã«æå®ãããã®ã®çåæéã«äŸåããŠããããšãè¡šæããŸãã
// æ»ãå€ã®åç
§ã®æå¹æéã¯åŒæ°iã«äŸåããŠãã
[[parameter_dependency(dependent{"return"}, providers{"i"})]]
int& f(bool b, int& i) {
static int s;
if (b) {
return s;
} else {
return i;
}
}
// æ»ãå€ã®åç
§ã®æå¹æéã¯åŒæ°left/rightã«äŸåããŠãã
[[parameter_dependency(dependent{"return"}, providers{"left", "right"})]]
int& g(bool b, int& left, int& right) {
if (b) {
return left;
} else {
return right;
}
}
class Car {
private:
Wheel wheels[4];
public:
// æ»ãå€ã®åç
§ã®æå¹æéã¯*thisãªããžã§ã¯ãã«äŸåããŠãã
[[parameter_dependency(dependent{"return"}, providers{"this"})]]
const Wheel& getDriverWheel() const {
return wheels[0];
}
}
ãã®å±æ§ã¯åç §ãšãªããžã§ã¯ãã®äŸåé¢ä¿ãæåã§è¡šæãããã®ã§ãã£ãŠããã®äŸåé¢ä¿ã確ç«ãåç §ãåç §ããŠãããªããžã§ã¯ãã®çåæéã延é·ãããã®ã§ã¯ãããŸããã
ãã®ãããªå±æ§ã¯ã©ã€ãã©ãªã®APIã«ãããŠããã¥ã¡ã³ããä»æ§èšè¿°ãšããŠäœ¿çšã§ããŸããããããªã³ãªãŒãªã©ã€ãã©ãªã§ããã°éç解æãªã©ä»ã®æ段ã«ãã£ãŠãã®äŸåé¢ä¿ãç¥ãããšãã§ãããããããŸãããã翻蚳åäœãåãããŠããå Žåã®ABIå¢çã®é¢æ°å®£èšã«ãããŠã¯ãã®ãããªå±æ§ã®æå¹æ§ã¯é«ãŸããŸãã
ãŸããã³ã³ãã€ã©ãéç解æããŒã«ããã®å±æ§ãèªèããããšã§ãã©ã€ãã¿ã€ã 解æã®æå©ããããããšãã§ããŸããäŸãã°å
ã»ã©ã®Car::getDriverWheel()
ã§ã¯
const Wheel& f() {
Car local;
return local.getDriverWheel(); // error?
}
ãã®å±æ§ãç¡ãïŒç¡èŠãããïŒå ŽåãgetDriverWheel()
ããè¿ãããåç
§ã®æå¹æéã¯åããããè¿œå ã®è§£æãªãã§ã¯ãã®äŸãæ£ããã®ãã©ãããå€æã§ããŸããïŒABIå¢çã®åããåŽã«å®è£
ãããå Žåããã®ãããªè§£æã¯äžå¯èœãããããªãïŒãããããparameter_dependency
å±æ§ã«ãã£ãŠæ»ãå€ã¯*this
ã®çåæéã«äŸåããŠããããšããããããã*this
ããªãã¡ããŒã«ã«ã®Car
ãªããžã§ã¯ãlocal
ã®å¯¿åœã«äŸåããŠããããšãããããã³ã³ãã€ã©ãéç解æåšã¯ãã®é¢æ°ã®å€åŽã«ãã®æ»ãå€ãæã¡åºãã®ã¯ééã£ãŠããããšãèªèã§ãããããããŸããã
äžã®æ¹ã®P2740R0ã§ã¯ããŒã«ã«å€æ°äŸåé¢ä¿ã®è§£æãå¿ èŠãšãªãããå°é£ã ã£ãå€æ®µéã®éæ¥åã«ãããã³ã°ãªã³ã°åç §çæãããã®ææ¡ã«ããå±æ§æå®ã«ãã£ãŠæåã§ã¯ãããŸããã³ã³ãã€ã©ãèªèå¯èœã«ãªããããããŸããããŸããããã¯ãã€ã³ã¿ã§ãæ©èœããC23ããã¯å±æ§æ§æãC++ãšåçã«ãªã£ãããããã®å±æ§ãCãšã®å ±éã³ãŒãã«æžãããšãã§ããéæ¥çã«Cã³ãŒãã®å®å šæ§åäžã«ã圹ç«ã€å¯èœæ§ããããŸãã
P2680R0ã®çŽ¹ä»ãšè§£èª¬ã¹ã©ã€ãã
P2680R0ã¯ãC++ãããå®å
šãªèšèªã«é²åãããŠããããšã®ç¬¬äžæ©ãšããŠå¥çŽããã°ã©ãã³ã°ã«çŠç¹ãåœãŠãå¯äœçšãUBã®æ±ãã«ã€ããŠè°è«ã®ããå¥çŽæ¡ä»¶åŒã®å®è¡ã¢ãã«ãconstexpr
ã®å®è¡ã¢ãã«ãšåããã®ã«ããããšãããã®ã§ãã
ãã®ã¹ã©ã€ãã¯SG21ã®ã¡ã³ãã«åããŠãã®å 容ã玹ä»ãããšãšãã«èæ¯ãªã©ã解説ãããã®ã®ããã§ãã
- P2680R0 Contracts for C++: Prioritizing Safety - WG21æ次ææ¡ææžãçºããïŒ2022幎10æïŒ
- P2700R0 Questions on P2680 âContracts for C++: Prioritizing Safetyâ - WG21æ次ææ¡ææžãçºããïŒ2022幎11æïŒ
æµ®åå°æ°ç¹ç°å¢ã®äžžãã¢ãŒãæå®é¢æ°std::fesetround()
ãéæšå¥šåããŠçœ®ãæããææ¡ã
std::fesetround()
ã«ã¯æ¬¡ã®ãããªåé¡ãããã移æ€å¯èœã§ãå¹æçã§ããªãããã§ã
FENV_ACCESS
ã#pragma
ããŠããªãå Žåãã³ã³ãã€ã©ã¯äžžãã¢ãŒããç¡èŠããæé©åãå®è¡ããããããããã®ãã¯ãã¯C++ã§ã¯ãµããŒããããŠããªããããC++ã§ã¯fesetround()
ãæ£ããåäœããããšãä¿èšŒã§ããªã- äžžãã¢ãŒããå€æŽããç¶æ ã§ãæšæºã®æ°åŠé¢æ°ããŠãŒã¶ãŒå®çŸ©é¢æ°ãåŒã³åºããçµæã¯äžè²«æ§ãç¡ããäºæž¬å¯èœã§ã¯ãªã
- äžžãã¢ãŒãã¯ã³ãŒãã®é åã«å¯ŸããŠæå®ããã®ã§ã¯ãªããããããã®æŒç®ã«å¯ŸããŠæå®ããå¿ èŠããã
- æ§ã
ãªäžžãã¢ãŒããè©Šãããšã§æµ®åå°æ°ç¹æ°ã®èª€å·®ãããçšåºŠææ¡ããããšãã§ãããã3ãšåãçç±ã«ããããã¯ã©ã³ãã ã«çµæãæŸä¹±ããããããããã«ãã·çšåºŠã®ãã®
- ãŸããããã°ã©ã ããžãã¯ãäžžãã¢ãŒãã«äŸåããŠããå Žåãã³ãŒããäžžãã¢ãŒããå€æŽããŠããå Žåããã®ã¢ãããŒãã¯ããŸããããªã
- ã³ã³ãã€ã©ã¯å®æ°åŒã«ãããŠã¯äžžãã¢ãŒããç¡èŠããåŸåã«ãããããã°ã©ããå®éã®çµæãäºæž¬ããããšãå°é£ã«ããŠãã
- ããäžžãã¢ãŒããé©çšããããã§çµæã確å®ãããããªãã°ãå®æ°åŒã«ãããŠãäžžãã¢ãŒããèæ ®ããªããã°ãªããªããããããããã¯Cã§ã¯çŠæ¢ãããŠãã
- ç¹ã«C++ã§ã¯ãããããæ£ããäžžããããŠããªãæŒç®ã«å¯Ÿããäžžãã¢ãŒãã®æå³ãäžæ確ãIEEEæšæºã¯æ£ããäžžããèŠæ±ããŠããããC++å®è£ ã¯é©åããŠããªã
Cã®FENV_ROUND
ãstd::fesetround()
ããã¯è¯ãæ¯ãèããããŸãããçµå±äžèšã®ããããã¯åé¡ãšãªããŸãã
ãããã®çç±ã«ãããstd::fesetround()
ã¯å®éã«ã¯ã»ãšãã©äœ¿çšãããŠããŸãããæ³å®ããããŠãŒã¹ã±ãŒã¹ã¯åºéæŒç®ããããã®ããã«èšç®çµæã®äžéãšäžéãåŸãå¿
èŠãããå Žåã§ããããã®ãããªçšéã¯ããŸãäžè¬çã§ã¯ãããŸããããŸããfenv.h
ã¯C++ãšçžæ§ãæªããCã®æ¹èšã«è¿œãã€ããŠããããCã§ãããã®æçšæ§ãçåèŠãããŠããããã§ãã
ç¹ã«ããã®æ©èœã¯æ°åŠé¢æ°ã®constexpr
åã®äœæ¥ã®éã«å€ãã®åé¡ãåŒãèµ·ãããŠãããå
šãŠã®æ°åŠé¢æ°ã¯fesetround()
ã«ããæé»ã®äžžãã¢ãŒãåŒæ°ãæã£ãŠããŸã£ãŠããããã®å€ã¯ã³ã³ãã€ã©ã«ãã£ãŠäºæž¬äžå¯èœãšãªãããããŠãŒã¶ãŒãæåŸ
ããæé©åãæ··ä¹±ãããããšã«ãªããŸããC++ã§ã¯ãæ°åŠã©ã€ãã©ãªãäžžãã¢ãŒããå°éãã¹ããã©ããããããã¯éæšæºã®äžžãã¢ãŒãã«ãããŠåççãªããšãè¡ãã¹ãããäžéæã§ãã
ãã®ãããªçç±ããããã®ææ¡ã§ã¯std::fesetround()
ãšstd::fegetround()
ãéæšå¥šã«ããããã§ãIEEEæšæºã®æå®ããæ£ããäžžãã«åŸã£ãæµ®åå°æ°ç¹æŒç®çµæãçæãã代æ¿æ©èœãè¿œå ããããšãææ¡ããŠããŸãã
ææ¡ãã代æ¿æ©èœã¯correctly_rounded
ãšããã¯ã©ã¹ã§ãã¡ã³ãé¢æ°ãšããŠIEEEæºæ ã®æµ®åå°æ°ç¹æŒç®ãè¡ãåçš®é¢æ°ãæäŸãããŸãã
template<floating_point F>
class correctly_rounded {
explicit correctly_rounded(F plain_value);
// Other expected constructors, destructor, assignment;
F to_plain() const;
...
// IEEEæºæ ã®ååæŒç®
correctly_rounded<F> operator+(correctly_rounded<F> y) const;
template<float_round_style r = round_to_nearest>
correctly_rounded<F> add(correctly_rounded<F> y) const;
correctly_rounded<F> operator*(correctly_rounded<F> y) const;
template<float_round_style r = round_to_nearest>
correctly_rounded<F> multiply(correctly_rounded<F> y) const;
...
// IEEEæºæ ã®æ°åŠé¢æ°
template<float_round_style r = round_to_nearest>
correctly_rounded<F> sqrt() const;
...
};
correctly_rounded<double> operator"" _d_round_to_nearest(const char
*);
correctly_rounded<double> operator"" _d_round_toward_infinity(const
char *);
correctly_rounded<F>
ã¯æµ®åå°æ°ç¹æ°åF
ã®å€ãã©ããããŠãæ£ããäžžããè¡ãåçš®æäœãæäŸããã¯ã©ã¹ã§ããã³ã³ã¹ãã©ã¯ã¿ã«å€ãæž¡ããããŠãŒã¶ãŒå®çŸ©ãªãã©ã«ã䜿çšããŠçæããåçš®æŒç®ã®éã«éåãã³ãã¬ãŒããã©ã¡ãŒã¿ãšããŠfloat_round_style
ã®å€ãããŠãããããšã§äžžãã¢ãŒããã³ã³ãã€ã«æã«æå®ããŸãã
std::fesetround()
- cpprefjp<cfenv>
- cpprefjp- FENV_ACCESS | Programming Place Plusãèšèªç·šãæšæºã©ã€ãã©ãªã®ãªãã¡ã¬ã³ã¹
- P2746 é²è¡ç¶æ³
å®æ°åŒã«ãããŠãvoid*
ãããã€ã³ã¿åãžã®å€æãèš±å¯ããææ¡ã
çŸåšãå®æ°åŒã«ãããŠã¯void*
åã®ãã€ã³ã¿ãä»»æã®T*
ã«ãã£ã¹ãããããšã¯æ瀺çã«çŠæ¢ãããŠãããä»®ã«ãã®ãã€ã³ã¿ãæ£ããT
ã®ãªããžã§ã¯ããæããŠããå Žåã§ãèš±å¯ãããŸããã
ãã®ã«ãŒã«ã¯å®æ°åŒã«ãããŠäžæ£ãªãã€ã³ã¿ã®èªã¿æ¿ãïŒtype punningïŒãèµ·ãããªãããã«ããããã§ãããconstexpr
ãC++ã®å®å
šãªãµãã»ãããšããæ¹éã«åºã¥ãããã®ã§ãããã ããvoid*
ããã®å€æããã€ãå±éºãšããããã§ã¯ãªããäžã«ã¯å®å
šãšåãã£ãŠãããã®ããããäžåŸã«çŠæ¢ãããŠããããšã«ãã£ãŠããã€ãã®äŸ¿å©ãªããŒã«ãã³ã³ãã€ã«æã«äœ¿çšã§ããªãå±
ããŠããŸãã
- åæ¶å»ãŠãŒãã£ãªãã£
- äŸãã°ã
function_ref
ã¯åæ¶å»ããŠä¿æããŠããåŒã³åºãå¯èœãªãã®ãžã®ãã€ã³ã¿ã埩垰ããããã«void*
ããã®å€æãå¿ èŠ
- äŸãã°ã
- é
眮
new
- é
眮
new
ã¯ãªããžã§ã¯ããæ§ç¯ããé åãã€ã³ã¿ãvoid*
ã§åãã std::construct_at()
ã§ã¯new
åŒã§å¯èœãªå šãŠã®åæåãã«ããŒã§ããŠãããïŒããã©ã«ãåæåã§ããªããªã©ïŒãã³ããŒçç¥ã劚ãã
- é
眮
- ãªããžã§ã¯ãã®é
延åæåïŒæªåæåé
åãªã©ïŒ
- é
眮
new
ãå¿ èŠãšãªã - é
眮
new
åé¿ã®ããã«ã¯æªåæåãªããžã§ã¯ããåé¡ãšãªã - çŸåšã
static_vector
ã®constexpr
察å¿ã§åé¡ãšãªã£ãŠãã
- é
眮
ãããã®ãŠãŒã¹ã±ãŒã¹ã®ãµããŒãã®ããã«ããã®ææ¡ã§ã¯çŸåšå®æ°åŒã§void*
ããT*
ãžã®ãã£ã¹ããçŠæ¢ããŠããäžæãåé€ããããšã§ãvoid*
ããã®ãã€ã³ã¿ã®åŸ©åž°ãå®æ°åŒã§ãå¯èœãšããããšãææ¡ããŠããŸãã
ãã ããvoid* -> T*
ãžã®å€æãè¡ããã€ã³ã¿ã¯äºãT*
ããstatic_cast<void*>
ã§åŸããããã®ã§ããå¿
èŠããããä»ã®å Žåã¯èš±å¯ãããŸãããããªãã¡ããã€ã³ã¿ãå®éã«æããªããžã§ã¯ãã®åã«å¿ãããã€ã³ã¿åãžã®å€æã®ã¿ãèš±å¯ããtype punningã®ãããªããšãå¯èœã«ããããã§ã¯ãããŸããã
ãŸããæªåæåé
åïŒé
延åæåå¯èœãªT
ã®é
åïŒãµããŒãã®ããã«ãunion
ã®ã¡ã³ããšãªã£ãŠããé
åã«å¯Ÿããé
眮new
ãæé»çã«é
åå
šäœã®çåæéãéå§ããããšãææ¡ããŠããŸãã
ãã®ææ¡ã®æ³å®ãããå®è£
äžã®æžå¿µã¯ããã®ãããªãã€ã³ã¿å€æãæ€èšŒããã³ã¹ãã§ããå®æ°åŒã«ããããã€ã³ã¿ã®è¿œè·¡ã³ã¹ããé«ãã€ãããã«ãªã£ãŠããŸããšãã³ã³ãã€ã«æéã®å¢å€§ãæããŸããããããvoid* -> T*
ãžã®å€æãçŠæ¢ãããŠããããšã«ãã£ãŠåæ¶å»ãŠãŒãã£ãªãã£ãé
眮new
ãªã©ãçŽæ¥çã«å©çšã§ããªãããã«ããããå¿
èŠãšãªã£ãæã«åå¥ã«std::construct_at
ã®ãããªãã®ãå°å
¥ããå¿
èŠããããŸãããã®ã³ã¹ãïŒèŠæ Œåãã³ã³ãã€ã©å®è£
ã®æéïŒã«æ¯ã¹ãã°ããã®ææ¡ãå®è£
ããã³ã¹ãã¯äœããšçè
ã®æ¹ã¯äž»åŒµããŠããŸãã
glvalueãæé»å€æã«ãã£ãŠäžæãªããžã§ã¯ããšããŠåç §ã«æçžãããå Žåãã³ã³ãã€ã«ãšã©ãŒãšããææ¡ã
次ã®ã³ãŒãã«ã¯äžç®æãã°ããããŸãã
struct X {
const std::map<std::string, int> d_map;
const std::pair<std::string, int>& d_first;
X(const std::map<std::string, int>& map)
: d_map(map)
, d_first(*d_map.begin())
{}
};
ã³ã³ã¹ãã©ã¯ã¿ã®map
ã¯åžžã«1èŠçŽ 以äžãããšããŠãåé¡ãããã®ã¯å
é èŠçŽ ã®åç
§ãd_first
ã«åã£ãŠãããšããã§ãã
std::map<K, V>
ã®èŠçŽ åã¯std::pair<const K, V>
ãªã®ã§d_first
ã®åstd::pair<std::string, int>
ã¯ééã£ãŠããŸãããšããããã®ããšèªäœã¯ã³ã³ãã€ã«ãšã©ãŒã«ãªãããæé»å€æã«ãã£ãŠstd::pair<std::string, int>
ã®äžæãªããžã§ã¯ããçæããããã®äžæãªããžã§ã¯ããd_first
ã«æçžãããŸãããããŠããã®äžæãªããžã§ã¯ãã®å¯¿åœã¯ã³ã³ã¹ãã©ã¯ã¿åŒã³åºããšå
±ã«çµäºããd_first
ã¯ãã³ã°ãªã³ã°åç
§ãšãªããŸãã
ãšã¯ãããã®äŸã¯ãã³ã³ã¹ãã©ã¯ã¿åæååãªã¹ãå ã§äžæãªããžã§ã¯ãã®åç §ãžã®æçžãèµ·ãã£ãå Žåã¯ill-formedããšããã«ãŒã«ã«ãã£ãŠã³ã³ãã€ã«ãšã©ãŒãšãªããŸãã
ãã ããã³ã³ã¹ãã©ã¯ã¿ã®å€ã§åãããšãèµ·ãããšã³ã³ãã€ã«ãšã©ãŒã«ã¯ãªããŸããã
struct Y {
std::map<std::string, int> d_map;
const std::pair<std::string, int>& first() const {
return *d_map.begin(); // äžæãªããžã§ã¯ããçæããã
}
};
ãã®first()
ã¯åžžã«ãã³ã°ãªã³ã°åç
§ãè¿ããŸããå
çšãšåæ§ã®çç±ã«ããstd::map<std::string, int>
ã®å
é èŠçŽ ã¯std::pair<std::string, int>
ã«æé»å€æãããreturn
æã§ã¯ãã®äžæãªããžã§ã¯ããåç
§ã«æçžããããã®åç
§ãreturn
ãããŸãããšããããreturn
æã§çæãããäžæãªããžã§ã¯ãã®å¯¿åœã¯ãã®return
æã®çµäºãŸã§ãšèŠå®ãããŠããããããã®å Žåã«äžæãªããžã§ã¯ãã®å¯¿åœã¯å»¶é·ãããããã®é¢æ°ã¯åžžã«ãã³ã°ãªã³ã°åç
§ãè¿ããŸãã
ãã®ãããªã³ãŒãã¯å¿ ãããC++ååŠè ã ããæžãã³ãŒãã§ã¯ãªããçµéšè±å¯ãªC++ããã°ã©ãã§ãæžããŠããŸãæãããããŸãããã®ãããã³ã³ã¹ãã©ã¯ã¿ã®åæååãªã¹ãïŒåã³ããã©ã«ãã¡ã³ãåæååïŒãšåæ§ã«ããã®ãããªå€æã«ããäžæãªããžã§ã¯ãã®åç §ãžã®æçžãèµ·ããå Žåãã³ã³ãã€ã«ãšã©ãŒã«ããããšããææ¡ã§ãã
ãã®ææ¡ã§ã¯ãåç
§ãè¿ãé¢æ°ã®return
æã§äžæãªããžã§ã¯ããåç
§ã«æçžãããå Žåãill-formedãšããããšãææ¡ããŠããŸããçŸåšååšããŠãããã®ãããªé¢æ°ã¯åžžã«ãã³ã°ãªã³ã°åç
§ãçæããŠãããæªå®çŸ©åäœã«é¥ã£ãŠããŸããåŸã£ãŠããã®ææ¡ã«ãã圱é¿ã¯UBãã³ã³ãã€ã«ãšã©ãŒãšããã ãã§ãã
ã³ã³ã¹ãã©ã¯ã¿åæååãšããã©ã«ãã¡ã³ãåæååã§åãããšãèµ·ããå Žåãill-formedã«ããCWG 1696ã®è°è«ã§ã¯ãåãçç±ã«ããè«äºãèµ·ããããšãªãæ¡æãããŠããããã®ææ¡ã®æ ¹æ ã¯ãã®æãšåç以äžã«åŒ·ããã®ã§ãããšæãããŸãã
ææ¡ããããµã³ãã«ã³ãŒã
auto&& f1() {
return 42; // ã³ã³ãã€ã«ãšã©ãŒ
}
const double& f2() {
static int x = 42;
return x; // ã³ã³ãã€ã«ãšã©ãŒ
}
auto&& id(auto&& r) {
return static_cast<decltype(r)&&>(r);
}
auto&& f3() {
return id(42); // OK, ãã ããã°ãšæããã
}
Cã®èšèªæ©èœã®ç¯å²ã§çºçãããã³ã°ãªã³ã°ãã€ã³ã¿ãæå¶ããææ¡ã
ããã¯ãäžã®æ¹ã§åºãŠããP2724R0ãP2730R0ãP2740R0ãP2742R0ã®å 容ãåç §ã§ã¯ãªããã€ã³ã¿ã«å¯ŸããŠé©çšãããã®ã§ãããã¡ãã®ææ¡ã§ãåæ§ã®ãœãªã¥ãŒã·ã§ã³ã¯ãã€ã³ã¿ã«å¯ŸããŠãææ¡ããŠããã®ã§å 容ã¯ã»ãŒåäžã§ãããã®ææ¡ã¯ãããã®ææ¡ããCã®ãã€ã³ã¿åãã®éšåããŸãšãããã®ã®ããã§ãã
ãã®ææ¡ã§ææ¡ãããŠããäºããŸãšãããšæ¬¡ã®ãããªãã®ã§ã
- ãã€ã³ã¿ã®å¯¿åœãå°œããåã«ãã®åç
§ãããªããžã§ã¯ãã®å¯¿åœãå°œããå Žåããªããžã§ã¯ãã®ã¢ãã¬ã¹ããã€ã³ã¿ã«ä»£å
¥ã§ããªã
- ãã€ã³ã¿ãè¿ãé¢æ°ãããããŒã«ã«å€æ°ã®ãã€ã³ã¿ãçŽæ¥
return
ããå Žåãã³ã³ãã€ã«ãšã©ãŒã«ãã - åæ§ã®ããšãé¢æ°å ã®ããŒã«ã«ã¹ã³ãŒãã§èµ·ããå Žåããšã©ãŒã«ãã
- ãã€ã³ã¿ãè¿ãé¢æ°ãããããŒã«ã«å€æ°ã®ãã€ã³ã¿ãçŽæ¥
- 1段éã®éæ¥åãåŠç
- ãã€ã³ã¿ãè¿ãé¢æ°ãããããŒã«ã«å€æ°ã®æ§é äœã¡ã³ãã®ãã€ã³ã¿ãçŽæ¥
return
ããå Žåããšã©ãŒã«ãã - ãã€ã³ã¿ãè¿ãé¢æ°ãããããŒã«ã«å€æ°ãžã®ãã€ã³ã¿ã代å
¥ããããã€ã³ã¿å€æ°ã
return
ããå Žåããšã©ãŒã«ãã
- ãã€ã³ã¿ãè¿ãé¢æ°ãããããŒã«ã«å€æ°ã®æ§é äœã¡ã³ãã®ãã€ã³ã¿ãçŽæ¥
parameter_dependency
å±æ§ã®å°å ¥- äžæãªããžã§ã¯ãã®å¯¿åœãè€åãªãã©ã«ã®å¯¿åœïŒvariable scopeïŒãšåãã«ãã
- ããŒã«ã«å®æ°äžæãªããžã§ã¯ããå¿
ãå®æ°åãããããã«ãã
const
ãªäžæãªããžã§ã¯ããã³ã³ãã€ã©ã«ãã£ãŠå®æ°åããããããããªãããšãªã£ãŠãããšãããå®æ°åãããããšå€æŽãã
1ã®äŸ
int* f() {
return & 1; // ãšã©ãŒ
}
int* g() {
int local = 1;
return &local; // ãšã©ãŒ
}
struct Point {
int x;
int y;
};
Point* h() {
Point local = {1, 3};
return &local; // ãšã©ãŒ
}
void i(bool b, int i) {
int* p = nullptr;
if (b) {
static int s = 0;
p = &s; // OK
} else {
int i = 0;
p = &i; // ãšã©ãŒ
}
...
}
2ã®äŸ
struct Point {
int x;
int y;
};
int* f() {
Point local = {1, 3};
return &local.y; // ãšã©ãŒ
}
Point* f() {
Point local = {1, 3};
Point* p = &local;
return p; // ãšã©ãŒ
}
3ã®äŸ
struct Point {
int x;
int y;
};
[[parameter_dependency(dependent{"return"}, providers{"point"})]]
Point* obfuscating_f(Point* point) {
return point;
}
Point* f() {
Point local = {1, 3};
return obfuscating_f(&local); // ãšã©ãŒ
}
4ã®äŸ
void f() {
int* i = &5; // or uninitialized
if (whatever) {
i = &7;
} else {
i = &9;
}
// iãå®å
šã«äœ¿çšã§ããïŒéæ¥åç
§ãå«ããŠïŒ
}
5ã®äŸ
const int* f() {
return & 1; // ãã³ã°ãªã³ã°ã§ã¯ãªããã°ããŒãã«å€æ°ãšåç
}
const int* f() {
const int local = 1;
return &local; // ãã³ã°ãªã³ã°ã§ã¯ãªããã°ããŒãã«å€æ°ãšåç
}
struct Point {
int x;
int y;
};
const Point* f() {
const Point local = {1, 3};
return &local; // ãã³ã°ãªã³ã°ã§ã¯ãªããã°ããŒãã«å€æ°ãšåç
}
struct Point {
int x;
int y;
};
const int* f() {
const Point local = {1, 3};
return &local.y; // ãã³ã°ãªã³ã°ã§ã¯ãªããã°ããŒãã«å€æ°ãšåç
}
å¥çŽæ¡ä»¶ã®ãã§ãã¯ã«é¢ãã现ããã«ãŒã«ã®ææ¡ã
C++26ã«åããŠå¥çŽæ©èœãåºããŠããã«ããã£ãŠãå¥çŽæ¡ä»¶ã®ååŒãã©ã®ããã«è©äŸ¡ãããã®ãã«ã€ããŠã®è©³çŽ°ã¯éèŠãªäºé ã§ãããçŸåšã®è°è«ã®äžå¿ã§ããããŸãããã®ææ¡ã¯ãå¥çŽæ¡ä»¶ã®è©äŸ¡ããã£ãããšèŠå®ããå¥çŽéåããã€çºçããããå€æããããã®ã«ãŒã«ãææ¡ãããã®ã§ãã
ãã®ææ¡ã®æŠèŠã¯æ¬¡ã®ãããªãã®ã§ã
- å¥çŽæ¡ä»¶ã¯æèçã«
bool
å€æå¯èœãªåŒã§ãããè©äŸ¡ããéã¯åŒã®è©äŸ¡ã«é¢ããC++ã®éåžžã®ã«ãŒã«ã«åŸã - å¥çŽæ¡ä»¶ã®è©äŸ¡ãå®äºãããã®çµæã
true
ã§ã¯ç¡ãæãå¥çŽéåãçºçããŠãã- å¥çŽæ¡ä»¶åŒã®è©äŸ¡çµæã
true
ãšãªãå Žåã¯å¥çŽéåãæå³ããããã以äžã®ã¢ã¯ã·ã§ã³ã¯çºçããªã - å¥çŽæ¡ä»¶åŒã®è©äŸ¡çµæã
false
ãšãªãå Žåã¯å¥çŽéåãçºçããŠãã - å¥çŽæ¡ä»¶åŒã®è©äŸ¡æã«äŸå€ãæããããå Žåã¯å¥çŽéåãçºçããŠãã
- å¥çŽæ¡ä»¶åŒãUBãå«ãå Žåãæ¬ é¥ãçºçãã
- å®è£ ã¯ãæ¬ é¥ïŒUBïŒãå¥çŽéåãšããŠæ±ãããšãæšå¥šãã
- æ£åžžã«è©äŸ¡ãããªããã®ä»ã®å¥çŽæ¡ä»¶ã¯æ£åžžã«åäœãã
bool
å€æã«å€±æããå Žåãªã©ãåŒã®è©äŸ¡ã«é¢ããC++ã®éåžžã®ã«ãŒã«ã«åŸã
- å¥çŽæ¡ä»¶åŒã®è©äŸ¡çµæã
- å¥çŽæ¡ä»¶ãè©äŸ¡ãããåæ°ã¯æªèŠå®ãéåã®æ€åºã®ããã«0å以äžãéåã®åŠçã®ããã«1å以äžè©äŸ¡ãããã
- å¥çŽæ¡ä»¶ã1åã ãè©äŸ¡ããããšã¯èš±å¯ããã
- å¥çŽæ¡ä»¶ã0åã ãè©äŸ¡ããããšã¯èš±å¯ããã
- æ¡ä»¶åŒã«å¯äœçšããªãå Žåããã®è©äŸ¡ãã¹ãããããããšãèš±å¯ãããŠãã
- ã³ã³ãã€ã©ãåãéåãæ€åºããåçã®åŒãèå¥ã§ããå Žåããã®ä»£æ¿åŒã®è©äŸ¡ã§æ¡ä»¶åŒã眮ãæããããšãã§ããïŒas-ifã«ãŒã«ã«åºã¥ãïŒ
- å¥çŽæ¡ä»¶ãè€æ°åè©äŸ¡ããããšã¯èš±å¯ããã
- è€æ°ã®å¥çŽæ¡ä»¶ãé£ç¶ããŠè©äŸ¡ãããå Žåããããã¯çžäºã«äžŠã¹æ¿ããŠè©äŸ¡ãããå¯èœæ§ããã
ç¹ã«3ã€ç®ã®èŠåã¯ãå¯äœçšãå®è³ªçã«çŠæ¢ãã€ã€ãå¥çŽæ¡ä»¶ã®ä»ã®å©çšæ³ãªã©ãŸã è°è«ã®æäžã«ãããŠãŒã¹ã±ãŒã¹ã蚱容ããããšãæå³ããŠããŸãã
std::initializer_list
ã®æé»ã®é
åãã¹ã¿ãã¯ã§ã¯ãªãéçã¹ãã¬ãŒãžã«é
眮ãããããã«ããææ¡ã
std::initializer_list<E>
ã®ãªããžã§ã¯ãã¯ãå®è£
ã«ãã£ãŠçæãããèŠçŽ æ°N
ã®const E
ã®é
åãªããžã§ã¯ããåç
§ãããããªãªããžã§ã¯ãã§ããã®æé»ã®é
åã®åèŠçŽ ã¯åæååã®å¯Ÿå¿ããèŠçŽ ããã³ããŒãããŠåæåãããŸããstd::initializer_list
ãåæååã«äœ¿çšããå Žåããã®ãããªæé»é
åã®åèŠçŽ ããããã«ã³ããŒãããŠåæåãããŸãã
struct X {
X(std::initializer_list<double> v);
};
void f() {
// ãã®ã³ãŒãã¯
X x{ 1,2,3 };
// ããæžãããã®ããã«åæåããã
const double __a[3] = {double{1}, double{2}, double{3}};
X x(std::initializer_list<double>(__a, __a+3));
}
æšæºã§ã¯ãå®è£ ã¯ãã®æé»é åããªãŒããªã³ãªãŒã¡ã¢ãªãŒïŒããªãã¡éçã¹ãã¬ãŒãžïŒã«é 眮ããŠäœ¿ãåãããšãã§ããããšã瀺åããŠããŸããããããããã¯å®è³ªçã«äžå¯èœãšãªã£ãŠããããã§ãã
void f(std::initializer_list<int> il);
void g() {
// ãã®{1, 2, 3}ã®é
åã¯éçã¹ãã¬ãŒãžã«é
眮ã§ãããïŒ
f({1,2,3});
}
int main() { g(); }
/// ã©ããå¥ã®ç¿»èš³åäœã§å®çŸ©ãããŠãããšãã
void g();
void f(std::initializer_list<int> il) {
static const int *ptr = nullptr;
if (ptr == nullptr) {
ptr = il.begin();
g();
} else {
// C++æºæ å®è£
ã¯ãã®ã¢ãµãŒããåžžã«ãã¹ãã
assert(ptr != il.begin());
}
}
C++23ã«æºæ ããå®è£
ã¯ãã®ã³ãŒãã§çæããã2ã€ã®æé»é
åïŒ1ã€ã¯main()
ã®g()
åŒã³åºãã§çæããããã®ãããäžã€ã¯ãã¹ãããf()
ã®äžã§ã®g()
åŒã³åºãã§çæããããã®ïŒãããããç°ãªãã¢ãã¬ã¹ãæã€ããã«ã³ã³ãã€ã«ããªããã°ãªããŸããïŒå®éãclang/GCC/MSVCã¯ãã®ããã«ã³ã³ãã€ã«ããŸãïŒã
ããã«ãã£ãŠãstd::initializer_list
ã®æé»ã®é
åãéçã¹ãã¬ãŒãžã«é
眮ããæé©åã¯å®è³ªçã«äžå¯èœã«ãªã£ãŠããŸãã
std::initializer_list
ã®æé»ã®é
åãéçã¹ãã¬ãŒãžã«é
眮ãããããšããªããšããããšã¯ãstd::initializer_list
ãåæåã«äœ¿ãå Žåã«ã¯ç®ã«ã¯èŠããªã2åã®ã³ããŒãåžžã«è¡ãããŠããããšã«ãªããŸãã
#include <vector>
int main() {
// vectorã®ãã®ãããªåæåã«ãããŠãåèŠçŽ ã¯2åã®ã³ããŒã䌎ã
std::vector vec = {1, 2, 3, 4, ...};
}
1åç®ã®ã³ããŒã¯å®æ°ïŒ{1, 2, 3, 4}
ïŒããstd::initializer_list
ã®æé»ã®é
åãžã®ã³ããŒã§ããã®å®æ°ã¯å³å€ã§ãããéçã¹ãã¬ãŒãžã«é
眮ããããã®ã§ãã2åç®ã®ã³ããŒã¯ãstd::initializer_list
ã®æé»ã®é
åããstd::vector
ã®åèŠçŽ ãžã®ã³ããŒã§ãã
#include <vector>
int main() {
// ãã®ã³ãŒãã¯æ¬¡ã®ãããªã³ãŒããšçãã
std::vector vec = {1, 2, 3, 4, ...};
// 1. éçã¹ãã¬ãŒãžïŒå®æ°ïŒããæé»é
åãžã®ã³ããŒ
const int __a[] = {int{1}, int{2}, int{3}, int{4}, ...};
// 2. æé»é
åããvectorã®ã¹ãã¬ãŒãžãžã®ã³ããŒ
std::vector<int> vec(__a.begin(), __a.end());
}
ãã®ãããªã³ããŒã¯ç¡é§ã§ããã§ããã°åæžããããã®ã§ãããäžæ¹ã§ãªã¹ãåæåãè¡ãéã¯ãã®èŠçŽ æ°ã¯ããã»ã©å€§ãããªãå Žåãå€ããå®éã«ã¯ãããŸã§æ°ã«ããªããŠãè¯ããããããŸããã
ãšããããC++26ã§ã¯#embed
ã«ãã£ãŠãã®åé¡ã¯äžå±€æ·±å»ã«ãªããŸã
void f() {
std::vector<char> v = {
#embed "2mb-image.png"
};
}
ãã¡ã€ã«2mb-image.png
ã2MBã®ãµã€ãºã®ãã¡ã€ã«ã ãšãããšããã®ã³ãŒãã¯ãŸã2MBã®æé»é
åãäœæããŸããããã«ãã£ãŠé¢æ°ã®ã¹ã¿ãã¯ã2MBæ¶è²»ãããããšã«ãªããŸããã¹ã¿ãã¯ãªãŒããŒãããŒãèµ·ãããªããŠãã2MBÃ2åã®ã³ããŒã¯ååãªãªãŒããŒããããšããŠèŠ³æž¬ãããã§ãããããããããã®åé¡ã¯ã³ãŒãäžããé ãããŠãããstd::initializer_list
ã®æ¯ãèããããç¥ããªããšæ°ã¥ãããšãå°é£ã§ãã
ãã®ææ¡ã¯ããã®åé¡ã®è§£æ±ºã®ããã«ãstd::initializer_list
ãå°å
¥ããæé»ã®é
åãéçã¹ãã¬ãŒãžã«é
眮ããå®è£
ãæ瀺çã«èš±å¯ããããã«æšæºã®èŠå®ã調æŽãããã®ã§ãã
void f(std::initializer_list<double> il);
void g(float x) {
f({1, x, 3});
}
void h() {
f({1, 2, 3});
}
// ãããã®åæåã¯ããããã次ã®ãããªã³ãŒããšç䟡ã«ãªã
void g(float x) {
const double __a[3] = {double{1}, double{x}, double{3}}; // ã¹ã¿ãã¯ã«é
眮
f(std::initializer_list<double>(__a, __a+3));
}
void h() {
static constexpr double __b[3] = {double{1}, double{2}, double{3}}; // éçã¹ãã¬ãŒãžã«é
眮
f(std::initializer_list<double>(__b, __b+3));
}
ã¹ã¿ãã¯ã§ã¯ãªãéçã¹ãã¬ãŒãžã«é 眮ãããããã«ãªãããšã§ã¹ã¿ãã¯ã®æ¶è²»ãåé¿ããããšãã§ããå®æ°->ã¹ã¿ãã¯ãžã®1åç®ã®ã³ããŒãæ¶ãå»ãããšãã§ããŸãã
ãã ãããã®ææ¡ã§ã¯ãã®ãããªå®è£
ã匷å¶ããã®ã§ã¯ãªãããããŸã§ããããïŒh()
ã®äŸã®ããã«å®è£
ããïŒããšãèš±å¯ããã«çããŠããŸãã
ãã®ææ¡ã®æ¹åæ§ã¯ãåæååãªã¹ãïŒ{...}
ïŒã®ã»ãã³ãã£ã¯ã¹ãæååãªãã©ã«ãšäžèŽãããããšã«ãããçŸåšæååãªãã©ã«ã§èš±å¯ãããŠããæé©åãïŒã³ã³ãã€ã©ãå®è£
å¯èœã§ããã°ïŒåæååãªã¹ãã§ãèš±å¯ããããšãããã®ã§ããããŸãã
std::initializer_list<int> i1 = {
#embed "very-large-file.png" // OK
};
void f2(std::initializer_list<int> ia,
std::initializer_list<int> ib) {
PERMIT(ia.begin() == ib.begin()); // éçã¹ãã¬ãŒãžã«é
眮ããåãã¯é
åã®äœ¿ãåããèš±å¯ãã
}
int main() {
f2({1,2,3}, {1,2,3});
}
const char *p1 = "hello world";
const char *p2 = "world";
PERMIT(p2 == p1 + 6); // çŸåšèš±å¯ãããŠããæ¯ãèã
std::initializer_list<int> i1 = {1,2,3,4,5};
std::initializer_list<int> i2 = {2,3,4};
PERMIT(i1.begin() == i2.begin() + 1); // ãã®ææ¡ã«ãã£ãŠèš±å¯ãããæ¯ãèã
å¥çŽæ¡ä»¶åŒã«å«ãŸããå¯äœçšã®æ±ãã«ã€ããŠãC++ã®ä»ã®å Žæãšåãæ±ãã«ããææ¡ã
ãã®ææ¡ã¯ãP2521R0ã«ããMVPä»æ§ãããŒã¹ãšããŠãçŸåšè°è«ã®äžå¿ã«ããå¥çŽæ¡ä»¶åŒã«å«ãŸããå¯äœçšã®åãæ±ãã«ã€ããŠä»ã®C++ã®åŒãšå·®å¥åããªãããšãææ¡ãããã®ã§ããå¯äœçšã®çŠæ¢ããã2å以äžåŒã°ããå¯èœæ§ãèŠå®ããïŒããšã«ããå¯äœçšãžã®äŸåã®çŠæ¢ïŒããææ¡ããªããã®ã§ãã
ãã®ææ¡ã§ã¯
- å¥çŽæ¡ä»¶åŒã¯ããããçš®é¡ã®å¯äœçšãæã¡ãã
- å¯äœçšã«ã€ããŠãäžé©æ Œã»æªå®çŸ©åäœã»å®è£ å®çŸ©ã®åäœããªã©ãšããªã
- ä»ã®C++ã®åŒã®æšæºçãªåäœãšåãåäœããã
- å¥çŽã®2ã€ã®å®è¡ã¢ãŒãã¯ãã³ã³ãã€ã«åã«å®è£
å®çŸ©ã®æ¹æ³ã«ãã£ãŠæ±ºå®ããã
- No_evalã¢ãŒãã§ã¯ãå¥çŽæ¡ä»¶ã¯è©äŸ¡ãããªãããããã«å«ãŸããå¯äœçšãèµ·ãããªã
- Eval_and_abortã¢ãŒãã§ã¯ãå¥çŽæ¡ä»¶åŒã¯äºåæ¡ä»¶ãšäºåŸæ¡ä»¶ä»ãã®é¢æ°åŒã³åºãããšã«äžåãã¢ãµãŒã·ã§ã³å®è¡ããšã«äžååŒã³åºããã
- å¥çŽæ¡ä»¶åŒã®å¯äœçšã¯ãåŒã®1åã®å®è¡ã«ã€ã1åçºçãã
- ã¢ãµãŒã·ã§ã³ã®å ŽåãæïŒã¹ããŒãã¡ã³ãïŒã«ãã£ãŠãã®é åºã決å®ãã
- äºåæ¡ä»¶ã®å Žåãé¢æ°åŒã³åºããšé¢æ°æ¬äœå®è¡ã®éã«å®è¡ããã
- äºåŸæ¡ä»¶ã®å Žåãé¢æ°æ¬äœå®è¡çµäºåŸãåŒã³åºãå ã®ç¶ç¶åŠçã®éå§åã«å®è¡ããã
ãã®ææ¡ã®äžã§ããas-ifã«ãŒã«ã«åŸã£ãŠå®è£ ã¯èŠ³æž¬å¯èœãªæ¯ãèãïŒobservable behaviorïŒãå€åããªãéãå¥çŽæ¡ä»¶åŒã®å®è¡ã䞊ã¹æ¿ãããçç¥ãããããããšã¯èš±å¯ãããŸãããã®ææ¡ã®æå³ã¯ããããã£ããšãããå«ããŠãå¥çŽæ¡ä»¶åŒãç¹å¥æ±ãããªãããšã«ãããŸãã
int x = 0;
void f() PRE(++x) // äºåæ¡ä»¶æå®ãšãã
{
...
}
int main() {
f();
return x;
}
ãã®ææ¡ã§ã¯ããã®ããã°ã©ã ã¯ill-formedã§ã¯ãªãæªå®çŸ©åäœãå«ã¿ãŸããããããŠãNo_evalã¢ãŒãã§ã¯0ãè¿ããEval_and_abortã¢ãŒãã§ã¯1ãè¿ããŸããå¥çŽæ¡ä»¶ãç¹å¥æ±ãããä»ã®ææ¡ã®å Žåã¯ãEval_and_abortã¢ãŒãã§0, 1, 2
ã®ãããããè¿ããŸãïŒçµæã1ã€ã«å®ãŸãããšãæšæºã«ãã£ãŠä¿èšŒãããªãïŒã
ãã®ææ¡ã«ããå¥çŽèšè¿°æã®å¥çŽæ¡ä»¶åŒã®ã»ãã³ãã£ã¯ã¹ã¯ãçŸåšã®C++ã«ãããæ®éã®åŒãšã»ãšãã©åãæ¯ãèããããããåçŽãã€çŽèŠ³çã§ããããŠãŒã¶ãŒã®æåŸ ãšç°ãªãæ¯ãèããããªãããïŒä»ã®ææ¡ãšæ¯ã¹ãŠïŒäœ¿ãããããã®ã«ãªã£ãŠããŸãã
std::format()
ã®ãã©ãŒãããæååæ§æã«ã€ããŠãå¹
/粟床ã®åçãªæå®æã®åã®æ€èšŒãã³ã³ãã€ã«æã«è¡ãããã«ããææ¡ã
std::format()
ã§ã¯ãã©ãŒãããåŸæååã®å¹
ã®æå®ãšãæµ®åå°æ°ç¹æ°ãã©ãŒãããæã®ç²ŸåºŠïŒå°æ°ç¹ãé€ããæ°å€ã®æ¡æ°ïŒãæå®ããããšãã§ããŸãã
int main() {
// æåå¹
ã®æå®
std::cout << std::format("|{:3}|\n", 10);
// 粟床ã®æå®
double v = 3.141592653589793;
std::cout << std::format("{:.5}\n", v);
}
åºåäŸ
| 10|
3.1416
ããã¯ãŸããå®è¡æã®åçæå®ãç°¡åã«è¡ãããã«ãè¿œå ã®åŒæ°ã«ãã£ãŠæå®ããããšãã§ããŸãã
int main() {
// å¹
ã®æå®ãåŒæ°ã§è¡ã
std::cout << std::format("|{:{}}|\n", 10, 4); // å¹
4ãèšå®ããã
// 粟床ã®æå®ãåŒæ°ã§è¡ã
double v = 3.141592653589793;
std::cout << std::format("{:.{}}\n", v, 3); // 粟床3æ¡ãèšå®ããã
}
åºåäŸ
| 10|
3.14
ãã®çœ®æãã£ãŒã«ãïŒ{}
ïŒå
ã«ãã¹ããã眮æãã£ãŒã«ãå
ã®ãªãã·ã§ã³ã«ã¯äœ¿çšããåŒæ°ã®ã€ã³ããã¯ã¹æå®ã®ã¿ãæå¹ã§ããã以å€ã®ãªãã·ã§ã³ã¯æ§æãšã©ãŒãšãªããŸãããŸãããã®ãã¹ããã眮æãã£ãŒã«ãã«ã¯æŽæ°å€ã®æå®ã®ã¿ãæå¹ã§ãã
ãã©ãŒãããæååã®åŠ¥åœæ§ã¯ã³ã³ãã€ã«æã«ãã§ãã¯ãããŸãããC++23æç¹ã«ãããŠãããã®ãã¹ããã眮æãã£ãŒã«ãã«å¯Ÿããåã®ãã§ãã¯ãã³ã³ãã€ã«æã«è¡ãããšãã§ããŸããã
std::format("{:>{}}", "hello", "10"); // å®è¡æãšã©ãŒ
ãã®å Žåã2ã€ç®ã®åŒæ°"10"
ãæååãªãã©ã«ã«ãªã£ãŠããããïŒæŽæ°åã§ãªããã°ãªããïŒæ§æãšã©ãŒãšãªãã¯ãã§ãããããã¯ã³ã³ãã€ã«æã§ã¯ãªãå®è¡æãšã©ãŒãšããŠå ±åãããŸãã
ãã®åé¡ã¯<format>
ã®å
ã«ãªã£ã{fmt}ã©ã€ãã©ãªã§ã¯æ¢ã«ä¿®æ£æžã¿ã§ãã³ã³ãã€ã«æã«ãšã©ãŒãçºããããšãã§ããŠããŸãããã®ææ¡ã¯ããããstd::format()
ã«å¯ŸããŠãé©çšãããã®ã§ãã
ãŠãŒã¶ãŒå®çŸ©åã§ãçµã¿èŸŒã¿åã§ããstd::format()
ã«æå®ãããåŒæ°ã«å¯Ÿãããã©ãŒãããæååã®ããŒã¹ã¯std::formatter<T>::parse()
ã§è¡ãããŸãããã©ãŒãããæååäžã®çœ®æãã£ãŒã«ãããšã«å¯Ÿå¿ããåŒæ°ãååŸããŠããã®åT
ã«ãã£ãŠstd::formatter<T>
ãªããžã§ã¯ããäœæããã.parse()
åŒã³åºãããŸãã.parse()
ã®åŒæ°ã«ã¯ããã©ãŒãããæååã«ãããçŸåšäœçœ®ã察å¿ããåŒæ°ã®æ
å ±ãæã£ãstd::basic_format_parse_context
ã®ãªããžã§ã¯ããæž¡ãããŸãã
眮æãã£ãŒã«ãã«ãã¹ããã眮æãã£ãŒã«ãã®å Žåãå€åŽã®çœ®æãã£ãŒã«ãã«å¯Ÿããparse()
ã«ãããŠãã¹ããã眮æãã£ãŒã«ããåŠçããå¿
èŠããããŸãããããã«æž¡ã£ãŠããstd::basic_format_parse_context
ãªããžã§ã¯ãã¯ãåŒæ°ã®å®éã®å€ããã³åæ
å ±ã«ã¢ã¯ã»ã¹ã§ããŸãããã§ããã®ã¯ã察å¿ããåŒæ°ãååšããŠããããšããã§ãã¯ããããšãšãã®ã€ã³ããã¯ã¹ãååŸããããšãããã§ãã
ããã«ãã£ãŠããã¹ããã眮æãã£ãŒã«ãã®ããŒã¹æã«ã¯å¯Ÿå¿ããåŒæ°ã«å¯Ÿããåã®ãã§ãã¯ãã³ã³ãã€ã«æã«è¡ããªããªã£ãŠããŸãã
æ¬å®¶{fmt}
ã§ããã®ãããã®æ§æã¯ã»ãŒåãã§ãããC++20以éã®æŽæ°ã«ãã£ãŠãã®åé¡ã«å¯ŸåŠããŠããŸããããã§ã¯ãbasic_format_parse_context
ã«check_dynamic_spec()
ãšããé¢æ°ãè¿œå ããŠãããã§ãã®ãã¹ããã眮æãã£ãŒã«ãã«å¯Ÿããåãã§ãã¯ãè¡ããŸãããã®ããã«ãã³ã³ãã€ã«æã®formatter::parse()
åŒã³åºãã§ã¯ãbasic_format_parse_context
ãªããžã§ã¯ãã®ä»£ããã«basic_format_parse_context
ãã掟çããcompile_parse_context
ãšããã¯ã©ã¹ã®ãªããžã§ã¯ããçæããŠãããparse()
ã«æž¡ããŸãã
parse()
ã¯å
ã»ã©ãšåæ§ã«å¯Ÿå¿ãã眮æãã£ãŒã«ãå
ãããŒã¹ããŠè¡ããŸããããã®éã«ãã¹ããã眮æãã£ãŒã«ãã«åœãã£ããšãïŒçµã¿èŸŒã¿åãªã®ã§ããã¯å¹
/粟床ã®åçæå®ãªãã·ã§ã³ïŒããã®åŒæ°ã®ååšãã§ãã¯ãã€ã³ããã¯ã¹ãã§ãã¯ãšåæã«ãbasic_format_parse_context::check_dynamic_spec()
ãåŒã³åºããŸããbasic_format_parse_context::check_dynamic_spec()
ã¯ã³ã³ãã€ã«æã«åŒã°ããå Žåã¯èªèº«ïŒ*this
ïŒãcompile_parse_context
ã§ããããšãç¥ã£ãŠããã®ã§ã*this
ãcompile_parse_context
ã«ã¢ãããã£ã¹ãããŠããcompile_parse_context::check_dynamic_spec()
ãåŒã³åºããŸãã
compile_parse_context
ã¯ãã®æ§ç¯æã«å
šãŠã®ãã©ãŒãããåŒæ°ã®åæ
å ±ãã€ã³ããã¯ã¹æ
å ±ãšå
±ã«åããŠä¿æããŠãããããcompile_parse_context::check_dynamic_spec()
ã«ã€ã³ããã¯ã¹ãæž¡ããŠããã°ã€ã³ããã¯ã¹ã«å¯Ÿå¿ããåæ
å ±ãååŸã§ããããã«ãã£ãŠå¹
/粟床ã®åçæå®ãªãã·ã§ã³ã®çœ®æãã£ãŒã«ãã«å¯Ÿå¿ããåŒæ°ãæŽæ°åãåŠãããã§ãã¯ããããšãã§ããŸãã
å®è£ ã€ã¡ãŒãž
// çµã¿èŸŒã¿åã®çš®é¡ãè¡šãåæå
enum class type {
none_type,
// Integer types should go first,
int_type,
uint_type,
long_long_type,
ulong_long_type,
int128_type,
uint128_type,
bool_type,
char_type,
last_integer_type = char_type,
// followed by floating-point types.
float_type,
double_type,
long_double_type,
last_numeric_type = long_double_type,
cstring_type,
string_type,
pointer_type,
custom_type
};
// åæåtypeã®å€ãæŽæ°åã§ããããå€å®
constexpr auto is_integral_type(type t) -> bool {
return t > type::none_type && t <= type::last_integer_type;
}
// {fmt}ã®æŽæ°ãããbasic_format_parse_contextå®çŸ©
template <typename Char, typename ErrorHandler>
class basic_format_parse_context : private ErrorHandler {
public:
// ãã®2ã€ã®é¢æ°ã¯C++20ãšåã
constexpr auto next_arg_id() -> int;
constexpr auto check_arg_id(int arg_id) -> void;
// å¹
/粟床ã®åçæå®ãªãã·ã§ã³ã®åãã§ãã¯ãè¡ãè¿œå ãããé¢æ°
constexpr auto check_dynamic_spec(int arg_id) -> void;
};
// ã³ã³ãã€ã«æã®ããŒã¹ã³ã³ããã¹ãå compile_parse_contextå®çŸ©
// ã³ã³ãã€ã«æã«parse()ã«æž¡ãããåã«æ§ç¯ãããbasic_format_parse_contextã«ããŠã³ãã£ã¹ãããŠæž¡ããã
template <typename Char, typename ErrorHandler>
class compile_parse_context : basic_format_parse_context<Char, ErrorHandler> {
// format()ã«æå®ãããåŒæ°ã®åæ
å ±é
å
std::span<type const> types_;
public:
constexpr auto arg_type(int id) const -> type { return types_[id]; }
// check_dynamic_spec()ã®ã³ã³ãã€ã«æçšå®è£
constexpr auto check_dynamic_spec(int arg_id) -> void {
if (arg_id < types_.size() and not is_integral_type(types_[arg_id])) {
// ãšã©ãŒå ±å
this->on_error("width/precision is not an integer");
}
}
};
// parse()å
ããã¯ãã¡ãã®check_dynamic_spec()ãåŒã³åºããã
template <typename Char, typename ErrorHandler>
constexpr auto basic_format_parse_context<Char, ErrorHandler>::check_dynamic_spec(int arg_id) -> void {
if consteval {
// ã³ã³ãã€ã«æã«åŒã°ããå Žåã¯èªèº«ãcompile_parse_contextãªããžã§ã¯ãã§ããããšãç¥ã£ãŠãããããå®å
šãªãã£ã¹ã
using compile_context = compile_parse_context<Char, ErrorHandler>;
static_cast<compile_context*>(this)->check_dynamic_spec(arg_id); // compile_parse_contextã®å®è£
ãåŒã³åºã
}
}
ãã®ãããªcheck_dynamic_spec()
ã®ã¢ãããŒãã¯æŽæ°åã®ã¿ãèæ
®ããŠããŸãããçµã¿èŸŒã¿åã®ãã©ãŒãããæå®ã«ãããŠã¯ååã§ãããã®ææ¡ã§ã¯äžæ©é²ãã§ããŠãŒã¶ãŒå®çŸ©åã§ãã¹ããã眮æãã£ãŒã«ããæ±ãéã«æŽæ°å以å€ã®åã䜿çšããå Žåã§ãã³ã³ãã€ã«æã«æ€èšŒå¯èœã«ããããšããŠããŸãã
ãã®ããã«ãã®ææ¡ã§ã¯ãcheck_dynamic_spec()
ãé¢æ°ãã³ãã¬ãŒãã«ããŠèŠæ±ããåããã³ãã¬ãŒããã©ã¡ãŒã¿ã«æå®ãã€ã€ããã¹ããã眮æãã£ãŒã«ãã«å¯Ÿå¿ããåŒæ°ã®ã€ã³ããã¯ã¹ãæž¡ãããšã§ããã®ã€ã³ããã¯ã¹ã®åŒæ°ã®åããã§ãã¯ããŸãã
ããããããšã§ãåãè¡šãåæåãæšæºã«è¿œå ãå
¬éããããšãé¿ããæåŸ
ããåãçŽæ¥æå®ãããšãã䜿ããããã€ã³ã¿ãŒãã§ãŒã¹ã«ãªããŸãããã ãã代åãšããŠãã®é¢æ°ãã³ãã¬ãŒããåŒã³åºãã«ã¯template
ããŒã¯ãŒããå¿
èŠã«ãªããŸãã
// ãŠãŒã¶ãŒå®çŸ©ç¹æ®åãšãã
template<typename T, typename charT>
struct formatter<T, char> {
auto parse(auto& ctx) {
// Tã«å¯Ÿããparse()å®è£
...
// check_dynamic_spec()ã®åŒã³åºã
ctx.template check_dynamic_spec<char>(id);
}
};
å€æŽäŸ
namespace std {
template<class charT>
class basic_format_parse_context {
...
public:
// ãã®ã³ã³ã¹ãã©ã¯ã¿ã¯åé€ïŒïŒ
constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
size_t num_args = 0) noexcept;
// è¿œå ããåãã§ãã¯é¢æ°
// idçªç®ã®åŒæ°ïŒãã©ãŒããã察象åŒæ°ïŒã«æåŸ
ããåãTsã«æå®ãã
template<class... Ts>
constexpr void check_dynamic_spec(size_t id);
// âãåŒã³åºããŠãŒãã£ãªãã£é¢æ°
constexpr void check_dynamic_spec_integral(size_t id);
constexpr void check_dynamic_spec_arithmetic(size_t id);
constexpr void check_dynamic_spec_string(size_t id);
};
}
ã³ã³ãã€ã«æã«ä»»æã®èšºæã¡ãã»ãŒãžãåºåã§ããããã«ããææ¡ã
çŸåšã®C++ã«ã¯ã³ã³ãã€ã«æã«èšºæã¡ãã»ãŒãžãåºåã§ãã䜿ããããæ¹æ³ããããŸãããäŸãã°static_assert
ã§ã¯ããã®ã¡ãã»ãŒãžããšã©ãŒã«åãããŠã«ã¹ã¿ãã€ãºããããšãã§ããŸããã
template <typename T>
void foo(T t) {
static_assert(sizeof(T) == 8, "All types must have size 8");
// ...
}
int main() {
foo('c'); // error
}
ãã®ãããªå Žåã«ã¢ãµãŒã·ã§ã³ã«é¢ããæ
å ±ïŒT
ã¯äœããsizeof(T)
ã¯ããã€ãïŒãæååãªãã©ã«ã«å«ããããšã¯ã§ããŸããã幞ããã³ã³ãã€ã©ã¯é·ããšã©ãŒã¡ãã»ãŒãžã®äžã«ãããã®æ
å ±ãåºåããŠãããå Žåãå€ãã§ãããT
ãã¡ã¿é¢æ°ã«ãã£ãŠå€æãããŠããå Žåãªã©ã«ã¯åºåãããªããªãããšããããŸãã
äžè¬çã«ãã³ãŒãäžã®ã¢ãµãŒã·ã§ã³ã«ãããŠã¯ãã®ã³ãŒããæžããŠããããã°ã©ãã®æ¹ããã®ã¢ãµãŒã·ã§ã³ã®ã¡ãã»ãŒãžã«ã€ããŠäœãæçšãªæ
å ±ãªã®ããç¥ã£ãŠããã¯ãã§ããã®æ¹æ³ããããã°ã³ã³ãã€ã©ãé 匵ããªããŠãããè¯ã蚺æã¡ãã»ãŒãžãåºåããããšãã§ããã¯ãã§ããããããçŸåšã¯static_assert
ã®2ã€ç®ã®åŒæ°ã¯æååãªãã©ã«éå®ã§ãããå®æ°åŒã§çæãããä»»æã®æååã䜿çšã§ããŸããã
ä»ã®ãšããã§ã¯ãstd::format
ã®ã³ã³ãã€ã«æãã©ãŒãããæååãã§ãã¯æã®èšºæã¡ãã»ãŒãžããããŸãã
auto f() -> std::string {
return std::format("{} {:d}", 5, "not a number");
}
äŸãã°ãã®äŸã§ã¯ã:d
ãconst char*
ã®ããã®ãã©ãŒãããæå®åã§ã¯ãªãããã³ã³ãã€ã«ãšã©ãŒãšãªããŸããããããã³ã³ãã€ã©ã®ãšã©ãŒã¡ãã»ãŒãžã¯å€ãã®å Žåäœãåå ã§ãšã©ãŒãèµ·ããã®ããå ±åã§ããŸããã
ãã®ãšã©ãŒå ±åã¡ã«ããºã ã¯static_assert
ã䜿çšããŠããããã§ã¯ãªããconsteval
é¢æ°å®è¡äžã«å®æ°åŒã§å®è¡äžå¯èœãªãã®ãçŸãããšã³ã³ãã€ã«ãšã©ãŒãšãªãããšãå©çšãããã®ã§ãthrow
åŒã®å®è¡ãæªå®çŸ©é¢æ°ã®åŒã³åºãã«ãã£ãŠã³ã³ãã€ã«ãšã©ãŒãçºçãããŠããŸããããã¯æ¬æ¥ã®çšæ³ã§ã¯ãªãããããã©ãŒãããæååã®ããŒã¹äžã«ã³ã³ãã€ã«ãšã©ãŒãçºçãããããšã¯ã§ããŠããç確ãªèšºæã¡ãã»ãŒãžãåºåããããšã¯ã§ããŸããã
ãã®å Žåã®ãšã©ãŒã¡ãã»ãŒãžããäŸãã°æ¬¡ã®ãããªãã®ã«ãªã£ãŠãããšãããããã®åå ãç¹å®ããã®ã¯ããªãç°¡åã«ãªããŸã
format("{} {:d}", int, const char*)
^ ^
'd' is an invalid type specifier for arguments of type 'const char*'
ãã®ã¡ãã»ãŒãžã¯å®ç§ã§ã¯ãªãã«ããŠããä»æ¥ã®èšºæã¡ãã»ãŒãžããã¯ã¯ããã«åªããŠããŸãã
ãã®ææ¡ã¯ã次ã®ããã«ä»æ¥ã®ã³ã³ãã€ã«æ蚺æã¡ãã»ãŒãžåºåã®çŸç¶æ¹åãå³ããã®ã§ãã
static_assert
ãæ¡åŒµããŠã第äºåŒæ°ã«æååãªãã©ã«ã ãã§ãªãæååç¯å²ãåãåããããã«ãã- æ°ããã³ã³ãã€ã«æ蚺æAPIã®è¿œå ïŒã³ã³ãã€ã«æåºåãè¡ãïŒ
std::constexpr_print_str(msg)
std::constexpr_print_str(msg, len)
- æ°ããã³ã³ãã€ã«æãšã©ãŒããªã¬ãŒAPIã®è¿œå ïŒã³ã³ãã€ã«ãšã©ãŒçºçãšèšºæã¡ãã»ãŒãžåºåãè¡ãïŒ
std::constexpr_error_str(msg)
std::constexpr_error_str(msg, len)
std::format()
ã®constexpr
察å¿ãè¿œæ±ãããšãäžèšAPIãæ¡åŒµã§ããstd::constexpr_print(fmt_str, args...)
std::constexpr_error(fmt_str, args...)
std::format_parse_error(fmt_str, args...)
- ãã©ãŒãããæååã®ã³ã³ãã€ã«æãã§ãã¯ã®çºã®ãŠãŒãã£ãªãã£ãã³ã³ãã€ã«æã«è©äŸ¡ããããš
constexpr_error()
ãåŒã³åºããå®è¡æã«è©äŸ¡ããããšformat_error
äŸå€ãæãã
- ãã©ãŒãããæååã®ã³ã³ãã€ã«æãã§ãã¯ã®çºã®ãŠãŒãã£ãªãã£ãã³ã³ãã€ã«æã«è©äŸ¡ããããš
static_assert
ã®åŒæ°ã¯ãstatic_assert(cond, string-literal, expression-list...)
ã®ããã«ããïŒã€ãŸããstd::format
ãåã蟌ãïŒäºãå¯èœã§ããããã®ææ¡ã§ã¯åã«static_assert(cond, string-range)
ã®ããã«ããããšãææ¡ããŠããŸããåè
ã®åœ¢åŒã ãšãstatic_assert(cond, "T{} must be a valid expression.")
ã®ããã«3çªç®ä»¥éã®åŒæ°ç¡ãã§åŒã°ããå Žåã«ææ§ã«ãªãçºã§ããã®å Žåã«æååãªãã©ã«ããã©ãŒãããæååãšããŠæ±ããªãããã«ãããšãã®äžè²«æ§ã倱ãããŸãïŒãã®ã¢ãããŒãã¯ä»¥åã®Rustã®panic!()
ãã¯ãã§æ¡çšãããŠããããã§ããã2021幎ã«èŠçŽãããããã§ãïŒã
ãŸããåè
ã®åœ¢åŒãåããšã©ã€ãã©ãªæ©èœã§ããstd::format()
ãèšèªæ©èœã§ããstatic_assert
ã«å®è³ªçã«åã蟌ãã§ããŸãäºã«ãªããèšèªæ©èœãè€éãªã©ã€ãã©ãªæ©èœã«äŸåããããšã«ãªã£ãããå°æ¥ã®æ¡åŒµã劚ããããšããŸãè¯ãããšããããŸããã
ãã®ãããªçç±ã«ããåŸè
ã®åœ¢åŒãæ¡çšããstatic_assert
+std::format()
ã¯æ瀺çã«æžãå¿
èŠããããŸãã
static_assert(cond, std::format("The value is {}", 42));
åé·ãªèšè¿°ã«ã¯ãªããŸãããçŸåšã§ããªãã³ã³ãã€ã«æ蚺æã¡ãã»ãŒãžã®æè»åãéæã§ããŸãã
ææ¡ãããŠããæ°ãã2çš®é¡ã®APIïŒstd::constexpr_print_str(), std::constexpr_error_str()
ïŒã¯manifestly constant evaluatedã§ããæã®ã¿å¹æãæã€ãã®ããã«æå®ãããŸããããã¯ãconstexpr
åŠçãææ©çã«å®è¡ãããå¯èœæ§ãããããã®å Žåã«ã¯ã¡ãã»ãŒãžãåºåããããšã©ãŒãçºçããããããªãçºã®èŠå®ã§ããäŸãã°ãconstexpr
é¢æ°ã®å®è¡äžã«throw
åŒã«åºäŒã£ãå Žåããã®æèãå¿
ãå®æ°åŒã§å®è¡ãããªããã°ãªããªããã®ã§ãªããã°ããã®åŠçã¯ããã§äžæããå®è¡æãŸã§å»¶æãããŸããmanifestly constant evaluatedãšã¯ãã®æ§ãªå Žåã®å®è¡ã§ã¯ãªãããšãæå®ããŠããŠãconstexpr
åŠçã®ã³ã³ãã€ã«æå®è¡ã確å®ããå Žåã«ã®ã¿ãã®å¹æãçºæ®ããããšãèšã£ãŠããŸãã
- C++
std::format
ãããã¯{fmt}ã®ã³ã³ãã€ã«æãã©ãŒãããæååãã§ãã¯ã®éè¡ - å°é¢ãèŠäžããå°å¹Žã®è¶³è¹Žã«ãããç§ - C++ constexpré¢æ°ãã€ã³ã¹ã¿ã³ã¹åããããšã - å°é¢ãèŠäžããå°å¹Žã®è¶³è¹Žã«ãããç§
- P2758 é²è¡ç¶æ³
WG21 Direction Group (DG)ã®å®å šæ§ã«ã€ããŠã®èŠè§£ã説æããææžã
ããã°ã©ãã³ã°èšèªã®å®å šæ§ã«ã€ããŠã®é¢å¿ã®é«ãŸããåããŠãC++ã®å°æ¥ã®æ¹åæ§ãšããŠå®å šæ§ãè¿œæ±ããŠããäºã¯ã»ãŒåºãŸã£ãŠããŸããããããã©ã®ããã«é²ããŠããã®ãã«ã€ããŠæèŠããŸãšããC++æšæºåå§å¡äŒã®æ§é ãããã»ã¹ãå®çŸ©ããããšãç®çãšããŠæžãããææžã§ãã
ãã®ææžã§ã¯ãããããæ§ç¯ããã«ããã£ãŠã®åºæ¬çãªèãæ¹ãæ瀺ããŠããŸã
- åºãç®ã«ä»ãããããã¬ãŒã ã¯ãŒã¯ã®ç¢ºç«ãç®æã
- ãã®ãã¬ãŒã ã¯ãŒã¯å ã§ãå®å šæ§ã«é¢ããå€æŽãè°è«ãã
- ãã®å€æŽãé©çšããå ŽæïŒèšèªã»ããŒã«çïŒã«ã€ããŠåæããã
- åŸæ¹äºææ§ã®æ±ãã«ã€ããŠã®æ¹åæ§ã«åæãã
- æãéèŠãªãã®ã«åªå é äœãã€ãã
ãã®ææžã§ã¯ãŸãããã®ãããªä»çµã¿ã¥ãããã©ã®ããã«é²ããŠããã®ãã«ã€ããŠæ±ºãŸã£ãŠãããããã®ããã«èæ ®ãã¹ãããšãåæç¥èçãèšè¿°ãããã®ãããªä»çµã¿ã¥ããã®ããã«å¿ èŠãªäœæ¥çã«ã€ããŠèª¬æããŠããŸãã
å®å šæ§ãšã»ãã¥ãªãã£ã«é¢ããŠ2022幎æ«ã«æ°èšãããSG23ãå©çšããŠããäºã«ãªãã®ãããããŸãããããã®ææžã¯ãããªãææ¡ãåã£ãŠãããã決ããŠãããããšãæ±ããŠããŸãã
çŸåšã®Networking TSã«P2300ã®sender/receiever
ãµããŒããå
¥ã蟌ãææ¡ã
Networking TSãP2300ã«ã€ããŠã¯ä»¥åã®èšäºãåç §
ãã®ææ¡ã¯ãNetworking TSã®çŸç¶ã®åé¡ã解決ããããã«ãP2300ã§ææ¡ãããŠããsender/receiever
ã«ããéåæãã¬ãŒã ã¯ãŒã¯ãNetworking TSã«çµã¿èŸŒãããšã§ãNetworking TSã®éåæãããã¯ãŒã¯æäœãP2300ããŒã¹ã§æ§ç¯ããããšãããã®ã§ãã
ãã®ææ¡ã§ã¯ãNetworking TSã®åææäœã«ã€ããŠã¯æãå ¥ããçŸç¶ã®åæ/éåææäœã®ã€ã³ã¿ãŒãã§ãŒã¹ãåºæ¬ãšããŠãP2300ã®éåæãã¬ãŒã ã¯ãŒã¯ã«ã¢ãããããããšããŠããŸãããã®éã«ãèšèšã«ããã€ãã®åå²ãçãããšããããããããããã®éžæè¢ã«ã€ããŠèª¬æããŠããŸãã説æã®ããã«ãäžéšã®éžæè¢ãéžæãã圢ã§åŸã®æ©èœã解説ããŠããéšåããããŸããããã®ææ¡ã®ç®çã¯éžæè¢ã瀺ããŠNetworking TSãšP2300調åã®ããã®è°è«ãä¿ããšããã«ãããŸãã
éåæãããã¯ãŒã¯æäœã«ãããŠã¯ãéåææ§ãæ±ãé©åãªã³ã³ããã¹ãïŒå®è¡ã³ã³ããã¹ãïŒã«åºã¥ããŠæäœãå®è¡ãããã®ãå¿
èŠã§ããP2300ã§ã¯ããã¯scheduler
ã§ãããéåæãããã¯ãŒã¯APIã§ã¹ã±ãžã¥ãŒã©ãã©ã®ããã«ååŸãããã«ã€ããŠããã€ãéžæè¢ããããŸãã
1ã€ç®ã¯ãAPIãsender
ãã¡ã¯ããªãšããŠãscheduler
ãåŒæ°ãšããŠããã«æž¡ããã®ã§ãããã®æ¹æ³ã§ã¯ãéåææäœãäœæããéã«ãã®ã¹ã±ãžã¥ãŒã©ãæ瀺ããå¿
èŠããããŸãã
auto make_accept(auto scheduler, auto& socket) {
return async::accept(scheduler, socket);
}
ããã§ãmake_accept()
ã¯ãŠãŒã¶ãŒå®çŸ©é¢æ°ïŒããããTCPéä¿¡ãªã©ã«ãããŠåŸ
ã¡åããè¡ãåŠçïŒã§ãããasync::accept()
ã¯ãã®ææ¡ã«ããéåæãããã¯ãŒã¯APIã®äžäŸã§ãã
ãã®å Žåã®éåæAPIã¯ãscheduler
ãšè¿œå åŒæ°ãåãåã£ãŠsender
ãè¿ãsender
ãã¡ã¯ããªãšãªããŸãã
2ã€ç®ã¯ãAPIãsender
ã¢ããã¿ãšããŠãã¹ã±ãžã¥ãŒã©ã¯äžæµã®sender
ããååŸãããã®ã§ãã
auto make_accept(auto scheduler, auto& socket) {
return schedule(scheduler)
| async::accept(socket);
}
ããã§äžæµã®sender
ãšã¯schedule(scheduler)
ã®ããšã§ãããmake_accept()
ã¯ãŠãŒã¶ãŒå®çŸ©é¢æ°ãªã®ã§APIïŒasync::accept
ïŒã«|
ã§åæãããsender
ã¯ãŠãŒã¶ãŒãçšæããä»»æã®ãã®ã§ããscheduler
ã¯ãããäžäœã®sender
ã«æå®ããããã®ãååŸããŠäœ¿çšããŸãã
ãã®å Žåã®éåæAPIã¯ãåŠçã«å¿
èŠãªåŒæ°ãåãåã£ãŠãã®åŠçãè¡šãsender
ãè¿ãsender
ã¢ããã¿ãšãªããŸãã
3è©°ãã¯ãAPIãsender
ãã¡ã¯ããªãšããŠãã¹ã±ãžã¥ãŒã©ã¯äžæµã®sender
ããååŸãããã®ã§ãããã®æ¹æ³ã§ã¯ãåŠçã°ã©ãã®äœ¿çšåŽïŒäžæµïŒãã䜿çšããã¹ã±ãžã¥ãŒã©ãäžããããšãã§ããŸãã
auto make_accept(auto scheduler, auto& socket) {
return on(scheduler, async::accept(socket));
}
on()
ã¯P2300ã®CPOã®äžã€ã§ãon(sc, se)
ã®ããã«åŒãã§sender
ã§ããse
ã®åŠçãscheduler
ã§ããsc
ã®ã³ã³ããã¹ãã§å®è¡ããsender
ãè¿ããŸãããã®äŸã§ã¯on
ã«ãã£ãŠãŸãscheduler
ãäžããŠããŸããããããããã«async::accept()
ã«|
ã§ä»ã®åŠçããã§ãŒã³ããåŸãããã®åŒã³åºãåã«scheduler
ãäžããŠããã®ã³ã³ããã¹ãã§å®è¡ããããšãã§ããŸãã
ãã®å Žåã®éåæAPIã¯ãåŠçã«å¿
èŠãªåŒæ°ãåãåã£ãŠãã®åŠçãè¡šãsender
ãè¿ãsender
ãã¡ã¯ããªãšãªããŸãã
2ãš3ã®éãã¯ãéåæAPIãåŠçã°ã©ãã®å
é ã«æ¥ãã®ãéäžã«æ¥ãã®ãã®èãæ¹ã®éãã§ãããããã«ãã£ãŠã°ã©ãã®åæ¹ãšåŸæ¹ã®ã©ã¡ãããå®è¡ã³ã³ããã¹ãã§ããscheduler
ãååŸããã®ããç°ãªã£ãŠããŸãã
1ãš2ã®å Žåã¯ãéåæAPIãçšããŠéåæãããã¯ãŒã¯æäœãæ§ç¯ããéã«æ¢ã«äœ¿çšããã¹ã±ãžã¥ãŒã©ãç¥ã£ãŠããïŒçšæããŠããïŒå¿ èŠããããŸããäžæ¹ã3ã®å Žåã¯ãã®å¿ èŠã¯ãªããéåæãããã¯ãŒã¯æäœãæ§ç¯ããåŸã§å®éã«ãããå®è¡ããå Žæã§äœ¿çšããã¹ã±ãžã¥ãŒã©ãæå®ããããšãã§ããŸãã
ãã®ããããã®ææ¡ã§ã¯3ã®ã¢ãããŒããä»®æ¡çšãã以éã®APIã説æããŠããŸãã
Networking TSã®éåæAPIã§ã¯ããã®ã³ãŒã«ããã¯é¢æ°ã®ã·ã°ããã£ã¯std::error_code
ãçšãã1ã€ã ãã§ãããä»ã®éžæè¢ã¯ãããŸãããP2300ã«ããéåæAPIã§ã¯ããšã©ãŒãæåãšãã£ãæ
å ±ã¯receiver
ãéããŠ3ã€ã®ãã£ãã«ã§éç¥ãããããããšã©ãŒãã³ããªã³ã°ã€ã³ã¿ãŒãã§ãŒã¹ã«è€æ°ã®éžæè¢ãçãŸããŸãã
1ã€ç®ã¯ãset_value
ãã£ãã«ã䜿çšããŠä»ã®è¿œå åŒæ°ãšäžç·ã«ãšã©ãŒãéç¥ãããã®ã§ããããã¯Networking TSã®éåæAPIãšè¿ãã䜿çšæã«ãªããŸãã
auto sender
= async::read(socket, buffer)
| then([](error_code const& ec, int n) { ... });
// ã³ã«ãŒãã³ã®å Žå
auto[ec, n] = co_await async::read(socket, buffer);
2ã€ç®ã¯ããšã©ãŒæç¡ã«ãã£ãŠç°ãªãset_value
ãã£ãã«ã䜿çšããããšã§ãæåãšãšã©ãŒã®çµè·¯ãåãããã®ã§ããã³ã«ãŒãã³ã§ã®ã·ã°ããã£ã¯1ã€ã«å¶éãããããããã®å Žåã¯ã³ã«ãŒãã³ã§äœ¿çšã§ããŸããã
auto sender
= async::read(socket, buffer)
| overload(
[](int n){ /* success path */ },
[](error_code const& ec){ /* error path */ }
);
ãŸããåŸç¶ã®åŠçã¯ãã®2ã€ã®ãã¹ã®åå²ã«å¯Ÿå¿ããŠåæ§ã«overload()
ã«ãã£ãŠç¶ç¶ããå¿
èŠãããå¯èœæ§ããããŸãã
3ã€ç®ã¯ãåã®éžæè¢ã«ããããšã©ãŒãã£ãã«ãšããŠset_value
ã§ã¯ãªãset_error
ã䜿çšãããã®ã§ãã
auto sender
= async::read(socket, buffer)
| then([](int n) { /* success path */ })
| upon_error([](error_code const& ec) { /* error path */ });
// ã³ã«ãŒãã³ã®å Žå
try {
int n = co_await async::read(socket, buffer);
// success path
} catch (error_code const& ec) {
// error path
}
ã³ã«ãŒãã³ã®å Žåã¯ãšã©ãŒãã£ãã«ãäŸå€ã«ãªã£ãŠããŸããŸãããæåçµè·¯ãšå€±æçµè·¯ãçµ±åãããããªsender
ã¢ã«ãŽãªãºã ã䜿çšããããšã§äŸå€ãåé¿ããããšã¯å¯èœã§ãã
4ã€ç®ã¯ã1~3ã®è€åçãªãã®ã§ããšã©ãŒã®é倧床ã«å¿ããŠãšã©ãŒãã£ãã«ã䜿ãåãããã®ã§ããããã¯èããããã ãã§ããŸãæå¹æ§ã¯ãªããšã¿ãªãããã®ãããµã³ãã«ã³ãŒãã¯èšèŒãããŠããŸããã
5ã€ç®ã¯ãstd::error_code
ãžã®åç
§ãéåæAPIã«æž¡ããŠããšã©ãŒå ±åã¯ããã§è¡ããã®ã§ãããã®å Žåããããæž¡ãããŠããªããšãã¯ä»ã®æ¹æ³ããšãããšãã§ããŸãã
error_code ec;
auto sender
= async::read(socket, buffer, ec)
| then([](int n) { ... });
// ã³ã«ãŒãã³ã®å Žå
int n = co_await async::read(socket, buffer, ec);
if (!ec) {
/* success path */;
} else {
/* error path */
}
ãã®å ŽåãNetworking TSã®åææäœãšäœ¿çšæãè¿ããªããŸãã
Networking TSã§ã¯ãããæäœã«ã€ããŠã¡ã³ãé¢æ°ãšéã¡ã³ãé¢æ°ã®äž¡æ¹ãæäŸããŠããŸããsocket
ãšãããšã³ãã£ãã£ã«å¯ŸããŠãã®ã¡ã³ããšããŠåçš®æäœãæäŸããããšã¯ä»ã®èšèªã§ãäžè¬çãªãã®ã§ãããããã»ãã®ãªãã·ã§ã³ã¯ååšããŸããããŸããIDEã«ããå
¥åè£å®ãéã¡ã³ãé¢æ°ãããã¡ã³ãé¢æ°ã®æ¹ãå¹ããããåŸåã«ãããŸãã
éã¡ã³ãé¢æ°ã®æäœãæäŸããå Žåãããã¯CPOãšããŠå®çŸ©ãããããšã«ãªããããããŸããããCPOã¯ã¡ã³ãé¢æ°ã«ã¯ãªãåŸãŸããããŸããããã¯ã©ã¹ã«å¯ŸããŠã¡ã³ãé¢æ°ãšããŠæäŸããŠãããšãæéã®çµéãšãšãã«ä»ã®å€ãã®æäœã圹å²ããã®ã¯ã©ã¹ã«éçŽãããŠããå¯èœæ§ããããŸããéåæãããã¯ãŒã¯æäœã«ã¯æœåšçã«å€ãã®ããªãšãŒã·ã§ã³ïŒãªãã·ã§ã³ïŒããããããéã¡ã³ãé¢æ°ãçšããæ¹ã管çããããã§ãããã
ããšãã°ãsender
ãè¿ãæäœã¯async
ãã³ã«ãŒãã³ã§äœ¿çšããå Žåã¯coro
ã®ããã«ã䜿çšç®çã«ãã£ãŠé©åãªåå空éã«é
眮ããããšãã§ãããããããŸããã
// senderã®å Žå
auto sender = async::read(socket, buffer)
| then([](auto&&...){ /* use result */ };
// ã³ã«ãŒãã³ã®å Žå
auto[ec, n] = co_await coro::read(socket, buffer);
P2300ã®CPOãsender
ã¢ã«ãŽãªãºã ã§ã¯ãäž»äœãšãªããšã³ãã£ãã£ãç¡ããããããã¯åžžã«éã¡ã³ãé¢æ°ãšããŠå®çŸ©ãããŸããNetworking TSã®å Žåã¯socket
ãšãããšã³ãã£ãã£ãããããããã®ã¡ã³ããšããŠåçš®æäœãå®çŸ©ããæ¹ã奜ãŸãããããããŸããããŸãããªãã·ã§ã³ã®å
šçš®é¡ãæäŸããéã¡ã³ãé¢æ°ãæäŸãããšãã§ããäžéšã®ãŠãŒã¹ã±ãŒã¹ã®ããã«ã¡ã³ãé¢æ°ãæäŸããããšã劚ããããã§ã¯ãããŸããã
ãããã¯ãŒã¯æäœïŒãããã¯ããäžè¬çãªI/OæäœïŒã¯ãç¹æ®ãªã³ã³ããã¹ãã§ã¹ã±ãžã¥ãŒãªã³ã°ããã察å¿ããscheduler
ã§å®è¡ãããããšãå¿
èŠã§ãããããã¯ãŒã¯æäœãã¹ã±ãžã¥ãŒã©ãšããåãããããã®ã€ã³ã¿ãŒãã§ãŒã¹ã«ã¯ããã€ãã®ãªãã·ã§ã³ããããŸãã
- ãããã¯ãŒã¯æäœãšã¹ã±ãžã¥ãŒã©ã¯ç§å¯ã®ãã£ãã«ã䜿çšãã
- ãã£ãšãç°¡åãªä»æ§ã ãããããã¯ãŒã¯æäœããŠãŒã¶ãŒå®çŸ©ã®ã¹ã±ãžã¥ãŒã©ã䜿çšã§ããªãå Žåãããããåºç€ãšãªãã¹ã±ãžã¥ãŒã©ãæœåºããæ¹æ³ã«ã€ããŠã®ãããã³ã«ãå¿ èŠã«ãªã
- åçš®I/Oæäœãäœããã®æ¹æ³ã§å
¬é/æœè±¡åãã
- ä»®æ³é¢æ°ãCPOãªã©ã䜿çšãã
- ããæ±çšçãšãªãããI/Oæäœã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯
sender
ã䜿çšãããã®ãããäœã¬ãã«ã«ãªãããã©ãããã©ãŒã åºæãšãªãå¯èœæ§ããã - äŸãã°ãéåæ
read_some()
ãio_uring(2)ã䜿çšããå Žåãread_some()
ã¯iovec
ãžã®ãã€ã³ã¿ïŒ2ã€ã®ãªã³ã°ãããã¡ã®ãã€ã³ã¿ïŒãæäŸããªããã°ãªããããªããã€ãã®ãã€ã³ã¿ã¯ãã®I/Oæäœãå®äºãããã¡ããæ¶è²»ããããŸã§åç¶ããå¿ èŠããããããã¯ãread_some()
ã«æž¡ããããããã¡ãšã¯ããªãç°ãªãã€ã³ã¿ãŒãã§ãŒã¹ãšãªãã- éåæI/Oãªã®ã§ã
read_some()
ã®åŒã³åºãã¯I/Oã®å®äºãåŸ ããã«åŒã³åºãåŽã«æ»ããããI/Oã®å®äºãŸã§ããã§äœ¿çšãããªãœãŒã¹ãã©ãã§ã©ããã£ãŠä¿æããŠããã®ããåé¡ãšãªã
- éåæI/Oãªã®ã§ã
- ã¹ã±ãžã¥ãŒã©ã€ã³ã¿ãŒãã§ãŒã¹ã¯è€æ°ã®å¥çŽïŒãµããŒãããI/Oæäœã«å¯ŸããŠ1ã€ã¥ã€ïŒãã¢ãã«åãããããã¯ãŒã¯æäœã¯I/Oæäœã®ç¶æ
ãªããžã§ã¯ãã«åã蟌ãŸãããªããžã§ã¯ããçæãã
- åI/Oã€ã³ã¿ãŒãã§ãŒã¹ã¯ããã®ç¶æ ãªããžã§ã¯ããå¿ èŠãªåœ¢ã§åãå ¥ãä¿åãã
- P1031ã®Low level file I/Oã©ã€ãã©ãªã§ææ¡ãããŠãããã®ãI/Oã¹ã±ãžã¥ãŒã©ãšãã
- Networking TSïŒAsioïŒã®ãã®ã䜿çšãããããããšçµ±åãã
io_context
ã¯1ã®ç§å¯ãã£ãã«ã䜿çšããŠããæ§å
Networking TSã«ã¯ãbasic_waitable_timer
ãšããã¿ã€ããŒã¯ã©ã¹ããããåºç€ãšãªãã¯ããã¯åãåŸ
æ©æ¹æ³ãªã©ã®ããã€ãã®ã¿ã€ããŒããããã£ããšã³ã³ãŒãããŠããŸããNetworking TSã«ããããã®ã¿ã€ããŒã¯ã©ã¹ã¯ããšã³ãã£ãã£ïŒsocket
çïŒããã£ã³ã»ã«ãããªã¬ãŒããããã«äœ¿çšãããŸããæäœããã£ã³ã»ã«å¯èœã§ãã£ãŠãããã£ã³ã»ã«ã¯æ瀺çã«æå®ããå¿
èŠããããŸãã
waitable_timer timer(/* timer settings */);
auto sender = wait_for(timer, 5s); // åŸ
æ©ã¯5ç§ã§ãã£ã³ã»ã«
// ã³ã«ãŒãã³ã®å Žå
co_await wait_for(timer, 5s);
sender/receiver
ã§ãã£ã³ã»ã«ãè¡ãå Žåã¯ããã£ã³ã»ã«ãè¡ããsender
ã«æ¥ç¶ãããreceiver
ã®std::stop_token
ã®äœ¿çšã«ãã£ãŠè¡ããŸãããã®ãããã¿ã€ããŒã¯ã©ã¹ã¯å¿
èŠãªããªããŸãã
ã¿ã€ããŒãå®çŸ©ããã«ã¯ãé©åãªsender
ãäœæããããé©åãªscheduler
ã§ã¹ã±ãžã¥ãŒãªã³ã°ããã®ãåççãšãªããŸãã
// 5ç§åŸ
æ©ããsenderãçæ
auto sender = wait_for(5s);
// ã³ã«ãŒãã³ã®å Žå
co_await wait_for(5s);
ãã ããã¿ã€ããŒã®ããããã£ãæå®ãããå Žåãªã©ã¯ããããã®èª¿æŽã1ã€ã®ãªããžã§ã¯ãã«ã«ãã»ã«åããŠããã®ãªããžã§ã¯ãã䜿ããŸããæ¹ãæãŸããå ŽåãèããããŸãããã®ãããäž¡æ¹ã®éžæè¢ããµããŒãããããšãåççãããããŸããã
åºæ¬çãªãããã¯ãŒã¯æäœã¯ããªãåçŽã§ããããµããŒããã¹ãæäœã®æ°ã¯ããã»ã©å€ãã¯ãããŸããããã®ããããããã¯ãŒã¯æäœã«æ³šåããNetworking TSã§ã¯åºç€ãšãªãI/OæäœïŒäŸãã°ãio_uringïŒãæäŸããå šãŠã®ãã®ãæäŸããå¿ èŠã¯ãããŸããããããããã®ãããªåºç€ã®I/Oæäœãè¶ ããŠãããé«ãã¬ãã«ã®ã¢ã«ãŽãªãºã ãåççã«æ§æå¯èœãšããããšã«æ³šåãã¹ãã§ãã
äŸãã°ãasync::read_some()
æäœã¯éšåçã«æžã蟌ãŸããŠããå¯èœæ§ã®ãããããã¡ãããŸãèªãããšãã§ããŸããããããããåžžã«å®å
šãªãããã¡ãèªãããããªããã°å€±æãããããªasync::read()
æäœãæ§æããããšãã§ããŸãã
åé¡ã¯ããã®ãããªã¢ã«ãŽãªãºã ã¯ã©ããææ¡ã«å«ãŸããã¹ãããã«ãããããããŸããã
async::read()
ãasync_write()
ã¯åãããããäŸã§ãããasync::resolve()
ã®ããã«éèªæãªã¢ã«ãŽãªãºã ã®äŸããããŸããããã§ã¯ãgetaddrinfo(3)ã䜿çšãããŸãããããã¯åææäœã§ããã察å¿ããéåæããŒãžã§ã³ã¯æäŸãããŠããŸãããéåæãã¬ãŒã ã¯ãŒã¯ãåä¹ã以äžã¯ããã®ãããªå Žåã§ãéåæããŒãžã§ã³ãæäŸããªããã°ãªããªãã§ãããã
sender
ã¢ã«ãŽãªãºã 以å€ã®éšåã§ããä»ã®èå³æ·±ãã³ã³ããŒãã³ããèããããŸã
- ã³ã«ãŒãã³å
ã§äœ¿çšãããéåæãããã¯ãŒã¯æäœã«ã¹ã±ãžã¥ãŒã©ã泚å
¥ããã³ã«ãŒãã³ã¿ã¹ã¯ïŒ
io_task
ïŒ async_scope
ïŒcppcoroã®ãã®ïŒãšäŒŒããäœããã®I/Oã¹ã±ãžã¥ãŒã©ã«é¢é£ããé©åãªã¹ã³ãŒããèšå®ããio_scope
- ãœã±ããã®å
šäºéæäœ
- åæèªã¿æžãæäœã®ã¹ã±ãžã¥ãŒãªã³ã°ã«ã¯ããããã¡ã®çæãšæ¶è²»ã«å¯Ÿå¿ãã
sender
ã€ã³ã¿ãŒãã§ãŒã¹ãæã€ãªã³ã°ãããã¡ã®ãããªãã®ãæçšãšæããã
- åæèªã¿æžãæäœã®ã¹ã±ãžã¥ãŒãªã³ã°ã«ã¯ããããã¡ã®çæãšæ¶è²»ã«å¯Ÿå¿ãã
ãããã¯ãŒã¯æäœã¯ãæäœãéå§ãããŠããå®äºãããŸã§ã®éã¯éã¢ã¯ãã£ãã«ãªããŸãããã®ããããã®ãããªæäœããã£ã³ã»ã«ããããã«ã¯äœããã®ãã£ã³ã»ã«æäœãèœåçã«ããªã¬ãŒããå¿
èŠããããŸãããã®ãããstd::stop_token/std::stop_source
ã®æäŸãããããªatomic bool
ã«ããåçŽãªãã¹ãã¯äžè¬çã«ããŸãæ©èœããŸããïŒã¹ã¬ããã®åŠçããã£ã³ã»ã«ãããããè€éãªåŠçãå¿
èŠãšãªãããïŒã
ãã®ããããã£ã³ã»ã«ã«std::stop_token/std::stop_source
ã䜿çšããïŒããã¯ã»ãŒç¢ºå®äºé
ïŒå Žåããã£ã³ã»ã«ã·ã°ãã«ãåä¿¡ããstd::stop_token
ã«ã³ãŒã«ããã¯ãæå®ããŠãããã§å
·äœçãªãã£ã³ã»ã«åŠçãè¡ãå¿
èŠããããŸããstop_token
ãno_stop_token
ã§ãªãéãïŒã€ãŸãæäœããã£ã³ã»ã«ããµããŒãããªãå Žå以å€ã¯ïŒã³ãŒã«ããã¯ã®ç»é²ãšè§£é€ã®äž¡æ¹ã§äœããã®åæãè¡ãå¿
èŠããããsocket
ã§ã®ããŒã¿åŠçäžã«ãã®æäœãç¹°ãè¿ããšããã©ãŒãã³ã¹ãäœäžããå¯èœæ§ããããŸãã
ããã®æäœã«å¯ŸããŠãã£ã³ã»ã«ãèšå®ããã®ã§ã¯ãªããsocket
ã®ãããªãšã³ãã£ãã£ã®åäœã§ãã£ã³ã»ã«ããµããŒãããäºãã§ãããããããŸããããã®å Žåã¯ãã©ã€ãã©ãªã«ããããçšåºŠã®ãµããŒããå¿
èŠãšãªããŸããäŸãã°ãããæäœããã£ã³ã»ã«ããããã«ããã®æäœããã£ã³ã»ã«ããé¢æ°ãçšæãããªã©ã§ãã
ãã®å Žåã§ããããã©ãŒãã³ã¹äœäžãé¿ããããã«ãstop_token
ã«ããã³ãŒã«ããã¯ç»é²ãçŠæ¢ããå¿
èŠããããããããŸãããäŸãã°ãwhen_all()
ã¢ã«ãŽãªãºã ã¯ãè€æ°ã®sender
ãåããŠããã€ãã®stop_token
ïŒno_stop_token
ã§ã¯ãªãïŒã䜿çšããreceiver
ã䜿çšããããšã«ãªããŸããããã®å Žåã§ããåä¿¡ããå®äºã·ã°ãã«ããã¹ãŠééããã€ã€ãno_stop_token
ãåŸç¶sender
ã«å
¬éããsender
ã¢ããã¿ãçšæãããšäŸ¿å©ãããããŸããã
ã·ã¹ãã ã«ãã£ãŠã¯ãäžè¬çãªãŠãŒã¹ã±ãŒã¹ã«å¯Ÿå¿ãããã£ã³ã»ã«æäœïŒã¿ã€ã ã¢ãŠããªã©ïŒãåããŠããå ŽåããããŸãããã®å Žåã«ããããç°¡åã«å©çšããããã«ããããã¯ãŒã¯æäœã«å¯Ÿå¿ããsender
ãšæéæå®ããã¿ã€ã ã¢ãŠãsender
ãååŸããããšãåççãããããŸãããã¿ã€ã ã¢ãŠãsender
ã¯ãsender
ïŒãããã¯ãŒã¯æäœïŒã®å®äºãæå®æéã®çµéïŒã¿ã€ããŒã®ã¿ã€ã ã¢ãŠãïŒãèµ·ãã£ãæã«ãããçæ¹ã®æäœããã£ã³ã»ã«ããŸãã
ã¿ã€ã ã¢ãŠãsender
ã¯ãå©çšå¯èœã§ããã°åºç€ãšãªãã·ã¹ãã ã®ã¿ã€ã ã¢ãŠãæ©æ§ãå©çšããŠæ©èœãæäŸããããã§ãªããã°ã¿ã€ããŒ+when_any
ã¢ã«ãŽãªãºã ã®åææäœã®ããã«æ¯èããã©ããäžã€ã®sender
ãå®äºããå Žåã«stop_token
ã«ãã£ãŠæ®ãã®sender
ã«ãã£ã³ã»ã«ãããããããªå®è£
ã«ãªãã§ãããã
ãã ããã®ãããã¯ãŒã¯æäœã«ããããã£ã³ã»ã«æ©æ§ã®æ±ãã«ã€ããŠã¯P2300ãšNetworking TSã®äž¡æ¹ã«çµéšããªããå®éšãšèšèšæ€èšãå¿ èŠãšãªãããã§ããP2300ã®äž»åŒµãããããªããã£ã³ã»ã«ãéåææäœã«ã«ãã»ã«åããæ¹æ³ã¯èå³æ·±ããã®ã§ã¯ãããŸãããæœåšçãªã³ã¹ããšãããåé¿ããæ¹æ³ãæ確ã«ã¯ãªã£ãŠããŸããã
ãã®ææ¡ã¯ãä»®ã®æèšãå«ãã§ãããã®ã®ããã®èšèšã¯ç¢ºå®ãããã®ã§ã¯ãªãããããªãè°è«ã«ãã£ãŠãããã®éžæè¢ã®äžããèšèšãéžæããŠããããšãæå³ããŠããŸãã
- ãããã¯ãŒã¯ - TCP - boostjp
- Linuxã«ãããéåæIOã®å®è£ ã«ã€ã㊠- Qiita
<stop_token>
- cpprefjp- P2762 é²è¡ç¶æ³
std::layout_stride
ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã®çæããã¬ã€ã¢ãŠããããã³ã°ãä¿®æ£ããææ¡ã
std::layout_stride
ã¯std::mdspan
ã®ã¬ã€ã¢ãŠããããã³ã°ãã«ã¹ã¿ãã€ãºããã¯ã©ã¹ã§ã次å
æ¯ã«strideãæå®ããã¬ã€ã¢ãŠããæ±ãçºã®ãã®ã§ãããã®ã¯ã©ã¹ã«ã¯ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ããããŸãããlayout_stride
ã®èŠçŽ æ°ïŒextentsïŒã®æå®ãå®å
šã«éçã§ããå Žåã«ç¡å¹ãªãããã³ã°ãçæããŸãã
std::layout_stride::mapping<std::extents<int, 4>> map;
// map.is_unique() == true;
// map(0) == 0;
// map(1) == 0;
// map(2) == 0;
// map(3) == 0;
ã¬ã€ã¢ãŠããããã³ã°ã¯ã©ã¹ã¯ããªã·ãŒã¯ã©ã¹ã§ããããã®å
¥ãåã®mapping<E>
ã¯ã©ã¹ã«ãã£ãŠã¬ã€ã¢ãŠããããã³ã°ãã«ã¹ã¿ã ããŸãããã³ãã¬ãŒããã©ã¡ãŒã¿E
ã«ã¯æ¬¡å
ãšèŠçŽ æ°ã®æ
å ±ããã€åïŒstd::extents
ãstd::dextents
ïŒãæå®ããstd::extents<I, N...>
ïŒI
ã¯æŽæ°åãN...
ã¯å次å
ã«å¯Ÿå¿ããèŠçŽ æ°ïŒã¯éçã«æ¬¡å
ãšèŠçŽ æ°ãæå®ããstd::dextents<I, N...>
ã¯åçãªæå®ãè¡ããïŒstd::dynamic_extent
ãå«ãããšãã§ããïŒãã®ã§ãã
ãã®äŸã®å Žåã®ãããã³ã°ã¯1次å
4èŠçŽ ã®é
åãè¡šããŠããã次å
ãšèŠçŽ æ°ã¯å®å
šã«éçã«æå®ãããŠããŠãlayout_stride::mapping
ãããã©ã«ãæ§ç¯ããŠããããstrideã¯æå®ãããŠããŸããïŒlayout_stride
ã¯ãã³ã³ã¹ãã©ã¯ã¿åŒæ°ã§strideã®æ
å ±ãæž¡ããŸãïŒãlayout_stride::mapping
ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¯default
å®è£
ãããŠãããããã«ãã£ãŠãlayout_stride::mapping
ã®æã€strideæ
å ±(次å
æ°D
ãšãããšãstd::array<std::size_t, D>
ã®ãããªé
å)ã¯å
šãŠ0ãšããŠåæåãããŸãã
layout_stride
ã«ãããããã³ã°ïŒlayout_stride::mapping::operator(i...)
ïŒã§ã¯ãi...
ã®å
é ããã®ã€ã³ããã¯ã¹ã次å
æ°ãšããŠãã®æ¬¡å
ã«å¯Ÿå¿ããstrideå€ïŒã³ã³ã¹ãã©ã¯ã¿ã§æå®ããããã®ïŒãããããã®ãã足ãäžããå€ããããã³ã°ããã€ã³ããã¯ã¹ãšããŠè¿ããŸãããã®ãããlayout_stride::mapping
ãããã©ã«ãæ§ç¯ãããšãããã«ãããããã³ã°ã¯ããããã€ã³ããã¯ã¹ã0
ã«åããã®ã«ãªããããã¯æããã«ééã£ããããã³ã°ã«ãªã£ãŠããŸãã
äžæ¹ã§ãä»ã®ã¬ã€ã¢ãŠããããã³ã°ã¯ã©ã¹ãstd::layout_right
ïŒè¡åªå
ã¬ã€ã¢ãŠããC/C++ã®éåžžã®å€æ¬¡å
é
åã®ã¬ã€ã¢ãŠãïŒãstd::layout_left
ïŒååªå
ã¬ã€ã¢ãŠããfortranãmatlabã®é
åã®ã¬ã€ã¢ãŠãïŒã§ã¯ãã®åé¡ã¯èµ·ãããŸããã
std::layout_left::mapping<std::extents<int, 4>> map;
// map.is_unique() == true;
// map(0) == 0;
// map(1) == 1;
// map(2) == 2;
// map(3) == 3;
ãã®ææ¡ã¯ãstd::layout_stride
ã®ãã®æåãä¿®æ£ããããšãããã®ã§ã次ã®2ã€ã®æ¹æ³ãæ瀺ããŠããŸãã
- extentsãå®å
šã«éçã§ããå Žåã®
std::layout_stride
ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ãåé€ - extentsãå®å
šã«éçã§ããå Žåã®
std::layout_stride
ã®ããã©ã«ãæ§ç¯ã¯ãstd::layout_right
ãšåããããã³ã°ãçæãã- strideãæå®ããªãå Žåã®ãã©ãŒã«ããã¯å
ãšããŠã¯ãC++ã®ããã©ã«ãã®ã¬ã€ã¢ãŠãã§ããè¡åªå
ãããªãã¡
std::layout_right
ãæãŸãã - å¯èœãªå Žåã¯ã
layout_stride::mapping
ã®ããªãã¢ã«ããã©ã«ãæ§ç¯ãç¶æãã- 次å æ°ã0ã§ããããåçèŠçŽ æ°ãæå®ãããŠããå Žå
- strideãæå®ããªãå Žåã®ãã©ãŒã«ããã¯å
ãšããŠã¯ãC++ã®ããã©ã«ãã®ã¬ã€ã¢ãŠãã§ããè¡åªå
ãããªãã¡
ä»ã®ã¬ã€ã¢ãŠããããã³ã°ã¯ã©ã¹ãšã®äžè²«æ§ãããã©ã«ãæ§ç¯ããµããŒãããæ¹ã䜿ãããããšèããããããšãªã©ããããã®ææ¡ã§ã¯2çªç®ã®æ¡ãææ¡ããŠããŸãããŸãããã®ææ¡ã¯C++23ã®æ¬ é¥å ±åïŒDRïŒãšããããšãæšå¥šããŠããŸãã
ãã®ææ¡ã¯2023幎2æã®IssaquahäŒè°ã§C++23ã«åããŠæ¡æãããŠããŸãïŒDRãšãªãããšã¯åé¿ãããŠããŸãïŒã
2022幎11æã®KonaäŒè°äžã«è¡ãããSG14ã®ãã€ããªããããŒãã£ã³ã°ã®è°äºé²ã
ã©ããªããšãè°è«ãããã®æŠèŠã ããèšãããŠããŸãã
2022幎12æ8æ¥ãã2023幎1æ12æ¥ã®éã«è¡ãããSG19ã®ããŒãã£ã³ã°ã®è°äºé²ã
ã©ããªããšãè°è«ãããã®æŠèŠã ããèšãããŠããŸãã
2022幎10æ12æ¥ãã2022幎12æ24æ¥ã®éã«è¡ãããSG16ã®ããŒãã£ã³ã°ã®è°äºé²ã
NBã³ã¡ã³ããææ¡ã®ã¬ãã¥ãŒãè°è«ã«ãããŠã誰ãã©ããªããšãçºèšããã詳现ã«èšé²ãããŠããŸãã
tuple-like
ãªãªããžã§ã¯ãããç¹å®ã®ã€ã³ããã¯ã¹ã®èŠçŽ ãæãåºãCPOã®ææ¡ã
äŸãã°ãstd::pair
ãèŠçŽ ãšããç¯å²ã«å¯ŸããŠäœãRangeã¢ã«ãŽãªãºã ãé©çšããããšããstd::pair
ãã®ãã®ããããããpair
ã®2ã€ã®èŠçŽ ã®ã©ã¡ããã«çç®ããå Žåãå€ãã§ããããRangeã¢ã«ãŽãªãºã ã§ã¯ãã®ããã«ãããžã§ã¯ã·ã§ã³ã䜿çšã§ããå
¥åç¯å²ã®èŠçŽ ãããã®1éšãæœåºããããã§ãã®çµæã«å¯ŸããŠã¢ã«ãŽãªãºã ãé©çšããããšãã§ããŸãã
std::vector<std::pair<int, int>> v{ {3, 1}, {2, 4}, {1, 7} };
std::ranges::sort(v, std::less{}, [](auto& x) {
return std::get<0>(x); // ããŒã«ãã£ãŠãœãŒããã
});
std::pair
ãªãã°ãããžã§ã¯ã·ã§ã³ã®ããã«ã¡ã³ãå€æ°ãã€ã³ã¿ã䜿çšã§ããŸãããstd::tuple
ã¯ã§ããªããããã®ããã«ã©ã ãåŒã«ãã£ãŠèšè¿°ããªããã°ãªãããå°ãåé·ã§ããããã«ã¯ãå
¥åç¯å²ã®èŠçŽ ãå³èŸºå€ã®å Žåãªã©ã«æ£ããåŠçããããšãæèãããšããã«åé·ã«ãªã£ãŠããŸããŸãã
// å€ã«ããŽãªã«ãããªãtuple-likeãªããžã§ã¯ãã«å¯Ÿãããããžã§ã¯ã·ã§ã³
[](auto&& x) -> auto&& {
return std::get<0>(std::forward<decltype(x)>(x)); // key-based sorting
}
ãã®ãããªå Žåã®ãããžã§ã¯ã·ã§ã³ã¯æ¬¡ã®ããã«æžãããšçæ³çã§ã
std::ranges::sort(v, std::less{}, std::get<0>);
ããããstd::get<0>
ã ãã§ã¯ãŸã ãã³ãã¬ãŒãã®ã€ã³ã¹ã¿ã³ã¹åãå®äºããªãããããã¯ã§ããŸããã
ä»ã®æ段ãšããŠãviews::elements
ãæãã€ããããããŸãããããã¯ãtuple-like
ãªããžã§ã¯ããèŠçŽ ãšããå
¥åç¯å²ããæå®ã€ã³ããã¯ã¹ã®èŠçŽ ãæœåºããç¯å²ã«å€æãããã®ã§ãããã ãããã¯ãããžã§ã¯ã·ã§ã³ã䜿çšããå Žåãšã¯ç°ãªãtuple-like
ãªããžã§ã¯ããããªãç¯å²ã®äžéšã®èŠçŽ ã ãã«çç®ãããã®ã§ãããå€æåŸã®ç¯å²ã«å¯Ÿããæäœã¯ãå
ã®ç¯å²ã«å¯ŸããŠåœ±é¿ãäžãããã®ã§ã¯ãããŸããã
// views::keysïŒviews::elements<0>ïŒã«ãã£ãŠã1ã€ç®ã®èŠçŽ ã ããããªãç¯å²ã«å€æããŠãœãŒã
std::ranges::sort(v | std::ranges::views::keys, std::less{});
for (auto& x : v) {
auto [key, val] = x;
std::cout << "Key = " << key << ", Value = " << val << std::endl;
}
// åºåäŸïŒããŒã®ã¿ããœãŒããããŠããŸãïŒ
// Key = 1, Value = 1
// Key = 2, Value = 4
// Key = 3, Value = 7
views::elements<I>
ã¯å
¥åç¯å²ã®åèŠçŽ ããstd::get<I>
ã«ãã£ãŠèŠçŽ ã®åç
§ãæœåºããŠããããèŠçŽ ãšããç¯å²ãçæããŸãããã®ãããelements_view
ã®åèŠçŽ ã«å¯Ÿããæäœã¯ãã®èŠçŽ ïŒå
ã®ç¯å²ã®åèŠçŽ ã®äžéšïŒã ãã«ãã圱é¿ãåãŒããŸããããã®ããããã®äŸã®ããã«elements_view
äžã§ãœãŒãããããšãããšãå
ã®ç¯å²ã®èŠçŽ ã¯åããããŒã ããswap
ãããŠããŸããŸãã
ãã®ããã«ãçŸåšã®ãšããtuple-like
ãªããžã§ã¯ããèŠçŽ ãšããç¯å²ã«å¯ŸããŠRangeã¢ã«ãŽãªãºã ãé©çšãæ£ããå°åœ±ãè¡ãã«ã¯ãã©ã ãåŒã«ããåé·ãªã³ãŒããé©åã«èšè¿°ãã以å€ã«æ¹æ³ã¯ãããŸãããC++23ã§è¿œå ãããzip_view
ã§ã¯ãã®èŠçŽ ã¯åžžã«tuple-like
ãªããžã§ã¯ããšãªãããããã®åé¡ã¯ããæ·±å»ã«ãªãå¯èœæ§ããããŸãã
ãã®ææ¡ã¯ãäžèšã®ãããªtuple-like
ãªããžã§ã¯ãã®å°åœ±ãè¡ãstd::ranges::get_element<I>
ãšããCPOãè¿œå ããããšã§ããã®åé¡ã解決ããããšãããã®ã§ãã
// get_element CPOã®å®£èšäŸ
namespace ranges {
inline namespace /* unspecified */ {
template <size_t I>
inline constexpr /* unspecified */ get_element = /* unspecified */;
}
inline constexpr auto get_key = get_element<0>;
inline constexpr auto get_value = get_element<1>;
}
ããã䜿çšãããšãåé ã®ã³ãŒãã¯æ¬¡ã®ããã«æžãããšãã§ããŸã
std::vector<std::pair<int, int>> v{ {3, 1}, {2, 4}, {1, 7} };
// pairã®1ã€ãã®ãªããžã§ã¯ãã«ãããœãŒã
std::ranges::sort(v, std::less{}, std::ranges::get_element<0>);
// ãããã¯
std::ranges::sort(v, std::less{}, std::ranges::get_key);
get_element<I>
ã¯elements_view
ãšã¯ç°ãªãRangeã¢ããã¿ã§ã¯ãªãtuple-like
ãªããžã§ã¯ããåŒæ°ã«åãCPOã§ãããå
¥åã®ãªããžã§ã¯ãããget<I>
ã«ãã£ãŠI
çªç®ã®èŠçŽ ãæœåºãããã®ã§ããããã¯ãã®ããã«Rangeã¢ã«ãŽãªãºã ã®ãããžã§ã¯ã·ã§ã³ã«ãããŠäœ¿çšããããšãæå³ããŠããŸãã
std::ranges::get
ãšããååã䜿çšããªãã®ã¯ãstd::ranges::subrange
ã®ããã«æäŸãããŠããstd::get
ãªãŒããŒããŒãããã§ã«ãã®ååã䜿çšããŠããããã§ããããæŒãã®ããŠå°å
¥ããããšãããšABIç Žå£ãæãããšãåé¿ããããã§ãããã ãå¯èœãªãã°std::ranges::get
ã䜿çšãããããããã®ãããªABiç Žå£ãåãå
¥ããããããæ¢ãããšãææ¡ãããŠããŸãã
ãã®ææ¡ã«å¯ŸããSG9ã®ã¬ãã¥ãŒã§ã¯ãstd::ranges::get
ãšããååã«ããã³ã³ã»ã³ãµã¹ã¯åŸãããŠããŸããããranges
åå空éã®å€ã«åºããŠstd::get_element
ã®ããã«ããããšã«ã³ã³ã»ã³ãµã¹ãããããã§ãã