ð TOP / ã¢ãã³C++ M8ãC++17ãïŒif constexprã»æ§é åæçž
ã¢ãã³ç¬¬8ç« ïŒãC++17ããã³ãã¬ãŒãé©åœïŒif constexpr ãšæ§é åæçž
SFINAEïŒenable_ifïŒã®éè¡ãè¬ãå»ãã³ã³ãã€ã«æåå²ãšã¿ãã«å±éã»ãã©ãŒã«ãåŒ
C++14ãŸã§ã®ãã³ãã¬ãŒãã¡ã¿ããã°ã©ãã³ã°ã«ãããŠãåã®çš®é¡ïŒæŽæ°åã»ãã€ã³ã¿åã»æµ®åå°æ°ç¹æ°ãªã©ïŒã«å¿ããŠåŠçãåå²ãããã«ã¯ãSFINAEïŒSubstitution Failure Is Not An ErrorïŒã®åçãå©çšãã std::enable_if ãäœéã«ãæžãé£ããå¿
èŠããããŸããããã®ã³ãŒãã¯è§£èªå°é£ã§ãã³ã³ãã€ã«ãšã©ãŒãåºãã°ç»é¢ãèŠãå°œããæå·ã®ãããªãšã©ãŒãã°ã«éçºè
ã¯çµ¶æããŠããŸãããC++17ã§å°å
¥ããããif constexprãã¯ãã³ã³ãã€ã«æã«æ¡ä»¶ãåœã®ãã©ã³ããå®å
šã«æšãŠå»ãïŒã³ãŒãçæããããªãïŒããšã§ãæ®éã® if æãšåãçŽæçãªæžãæ¹ã§ååå²ãå®çŸããæŽå²ç転æç¹ãšãªããŸãããããã«ãæ§é äœããã¢ã1è¡ã§å解代å
¥ãããæ§é åæçžïŒStructured BindingsïŒããå¯å€åŒæ°ãã³ãã¬ãŒãã®å±éã1è¡ã§èšè¿°ããããã©ãŒã«ãåŒïŒFold ExpressionsïŒãããããŠã¹ã³ãŒãæ±æãé²ããåæåæä»ã ifããçµã¿åãããC++ã®ã¡ã¿ããã°ã©ãã³ã°ãšããŒã¿èµ°æ»ã¯åçãªãšã¬ã¬ã³ã¹ãæã«å
¥ããŸããã
M8.1 SFINAEïŒstd::enable_ifïŒã®æªå€¢ãšã³ã³ãã€ã«æ if ã®å€æã
é£è§£ã極ããC++11/14ã®ãã³ãã¬ãŒãåå岿æ³ãšãif constexpr ããããããé©åœçã·ã³ãã«ããæ¯èŒããŸãã
ð§ ãã³ã®ã³å
茩
ã·ãã¯ãå
çïŒãæŽæ°åãªããããã·ããã§é«éåãããã€ã³ã¿åãªãäžèº«ãéåç
§ããæµ®åå°æ°ç¹ãªãéåžžèšç®ããããšããæ±çšé¢æ°ãæžãããšãããã§ãããstd::enable_if ã®æ§æãé£ããããŠã³ã³ãã€ã«ãéããŸããâŠâŠïŒãšã©ãŒã100è¡åºãŸããïŒ
ð»ââïž ã·ãã¯ãå
ç
ãµãã£ãµãã£ãµãïŒSFINAEïŒçœ®æå€±æã¯ãšã©ãŒã«ãããïŒã®é»éè¡ãããªïŒãªãŒããŒããŒãã®è§£æ±ºé åºããã³ãã¬ãŒãç¹æ®åãé§äœ¿ããŠãã³ã³ãã€ã©ãéšãããã«æžãææ³ãããäžçäžã®ãããããã§äœåæéãæµªè²»ããŠããã®ããã
ð§ ãã³ã®ã³å
茩
ãæ®éã® if æãã§ããã T ãæŽæ°ãªããããããã§ãªããªãããããšæžãããšã¯ã§ããªããã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
ããããã C++17 ã§å°å
¥ããããif constexprãããïŒæ¡ä»¶åŒãã³ã³ãã€ã«æã«è©äŸ¡ãããåèŽããªãæ¹ã®ãã©ã³ãã¯ã³ã³ãã€ã©ã綺éºãµãããªæ¶æ»
ãããŠããããæ®éã® if æãšåãæèŠã§ã¡ã¿ããã°ã©ãã³ã°ãã§ããã®ããïŒ
M8.2 æ§é åæçžïŒStructured BindingsïŒïŒã¿ãã«ã»æ§é äœã»ãã¢ã®å解代å
¥
auto [a, b, c] ã«ããçŽæçãªè€æ°å€åãåããšããããèµ°æ»ã®åçãªç°¡çŽ åããã¹ã¿ãŒããŸãã
ð§ ãã³ã®ã³å
茩
std::map ã§æµã®ãªã¹ããã«ãŒããããšãããã€ããit->firstããšããit->secondãã£ãŠæžãã®ãçŽæçãããªããŠå€§å«ãã§ããããæµIDããšãæµããŒã¿ãã£ãŠååã§çŽæ¥åãåãããã§ãïŒ
ð»ââïž ã·ãã¯ãå
ç
ãµãã£ãµãïŒC++17ã®ãæ§é åæçžïŒStructured BindingsïŒãã䜿ãã°ã`for (const auto& [id, enemy] : enemyMap)` ãšæžãã ãã§äžçºè§£æ±ºããïŒ
ð§ ãã³ã®ã³å
茩
ããã£ïŒJavaScript ã Python ã®åå²ä»£å
¥ïŒDestructuringïŒã¿ããã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
ããããïŒãããC++ã®æ§é åæçžã¯ãå€ã³ããŒã ãã§ãªããåç
§ïŒauto&ïŒãã§ãåãåãããããéããªããžã§ã¯ãã®ã³ããŒããŒããããïŒ
M8.3 å®åã®é ãã䞻圹ïŒåæåæä»ã if ãšãã©ãŒã«ãåŒïŒFold ExpressionsïŒ
ã¹ã³ãŒãæ±æãå®å
šé²æ¢ãã if with initializer ãšãå¯å€åŒæ°ãã³ãã¬ãŒãã1è¡ã«åçž®ãããã©ãŒã«ãåŒãåŠã³ãŸãã
ð§ ãã³ã®ã³å
茩
å
çïŒãããããèŠçŽ ãæ¢ããšãããauto it = map.find(key); if (it != map.end())ãã£ãŠæžããšãif æã®å€åŽã«ã it 倿°ãçãæ®ã£ãŠã¹ã³ãŒããæ±ããã®ãå«ã§ããã
ð»ââïž ã·ãã¯ãå
ç
ããïŒããã§ãåæåæä»ã if (if with initializer)ãã®åºçªããïŒ`if (auto it = map.find(key); it != map.end())` ãšæžãã°ãit ã®å¯¿åœã¯ if ãããã¯ã®äžã ãã«éå®ãããïŒ
ð§ ãã³ã®ã³å
茩
第4ç« ïŒM4ïŒã§ç¿ã£ãå¯å€åŒæ°ãã³ãã¬ãŒãïŒArgs...ïŒã®å±éãããã£ãšç°¡åã«æžããããã«ãªã£ããšèããŸããïŒ
ð»ââïž ã·ãã¯ãå
ç
ãããC++17ã®ããã©ãŒã«ãåŒïŒFold ExpressionsïŒãããïŒM4ã§ã¯ååž°é¢æ°ããããŒé
åããªãã¯ã䜿ã£ãŠå±éããŠãã£ãããC++17ãªã `(... + args)` ãšæžãã ãã§å
šåŒæ°ã®åèšãåºåã1è¡ã§æžããã®ããïŒ
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
åæåæä»ã if / switch : `if (auto it = map.find(key); it != map.end())` ã®ããã«æ¡ä»¶å€å®çŽåã«å€æ°ãã¹ã³ãŒãéå®å®£èšããã¹ã³ãŒãæ±æã鲿¢ããã©ãŒã«ãåŒïŒFold ExpressionsïŒ : `(... + args)` ã `((std::cout << args << " "), ...)` ã®ããã«ãå¯å€åŒæ°ãã©ã¡ãŒã¿ããã¯ãååž°ãªãã§1è¡ã§å±éå¯èœã
M8.4 宿ŠïŒã²ãŒã å
æ±çšã€ãã³ããã£ã¹ãããã£ãšãã±ãããã³ãŒã
if constexpr ãšæ§é åæçžãèåãããåå®å
šãã€è¶
é«éãªã²ãŒã ã€ãã³ããã¹ãæ§ç¯ããŸãã
ð§ ãã³ã®ã³å
茩
ã·ãã¯ãå
çïŒãã¡ãŒãžã€ãã³ããã¹ã³ã¢å ç®ã€ãã³ããã¢ã€ãã ååŸã€ãã³ããå
šéš1ã€ã®æ±çšãã£ã¹ãããã£ã«éçŽããŠãif constexpr ã§åå®å
šã«æ¯ãåããŠã¿ãŸãïŒ
ð»ââïž ã·ãã¯ãå
ç
èŠäºããïŒä»®æ³é¢æ°ããŒãã«ïŒvtableïŒã®ãªãŒããŒãããããã£ã¹ãã®å±éºãå®å
šãŒãã§ãã³ã³ãã€ã«æã«æé«éã®ã³ãŒããžãšå±éããããïŒ
ð EventDispatcher.cpp
#include <iostream>
#include <string>
// ã€ãã³ãå®çŸ©
struct DamageEvent {
int targetId;
int amount;
bool isCritical;
};
struct ScoreEvent {
std::string reason;
int points;
};
// æ±çšã€ãã³ããã£ã¹ãããã£
class GameEventDispatcher {
public:
template <typename TEvent>
void dispatch(const TEvent& event) {
if constexpr (std::is_same_v<TEvent, DamageEvent>) {
// æ§é åæçžã§ã€ãã³ãäžèº«ãå±é
const auto& [target, dmg, crit] = event;
std::cout << "âïž ãã¡ãŒãžé©çš: 察象=" << target
<< ", ãã¡ãŒãž=" << dmg
<< (crit ? " [CRITICAL!]" : "") << "\n";
}
else if constexpr (std::is_same_v<TEvent, ScoreEvent>) {
const auto& [reason, pts] = event;
std::cout << "â ã¹ã³ã¢ç²åŸ: " << reason << " (+" << pts << " pts)\n";
}
else {
static_assert(!sizeof(TEvent), "æªå¯Ÿå¿ã®ã€ãã³ãåãéä¿¡ãããŸããïŒ");
}
}
};
int main() {
std::cout << "--- M8 ã€ãã³ããã£ã¹ãããã·ã¹ãã ---" << std::endl;
GameEventDispatcher bus;
// ãã¡ãŒãžã€ãã³ãéä¿¡
bus.dispatch(DamageEvent{1, 150, true});
// ã¹ã³ã¢ã€ãã³ãéä¿¡
bus.dispatch(ScoreEvent{"ã€ã³ããŒããŒæç Ž", 300});
return 0;
}
ð ç解床ãã§ãã¯ã¯ã€ãº
Q1. C++17ã® if constexpr ããã³ãã¬ãŒã颿°å
ã§äœ¿çšããéãæ¡ä»¶ãåœïŒfalseïŒãšãªã£ãåå²ã®ã³ãŒãã¯ã©ãæ±ãããŸããïŒ
1. å®è¡æã«ã¹ããããããã ãã§ãéåžžéãæ©æ¢°èªã³ãŒããçæããã 2. ã³ã³ãã€ã«å¯Ÿè±¡ããå®å
šã«é€å€ïŒDiscarded StatementïŒããããã®åå²å
ã«å«ãŸããåäžé©åã³ãŒãããã£ãŠãæ§æãšã©ãŒã«ãªããããã€ããªãçæãããªã 3. æ¡ä»¶ãåœã®ãã©ã³ããããå Žåãã³ã³ãã€ã©ãèŠåãåºåãã 4. å®è¡æã«äžåºŠã ãè©äŸ¡ããã以åŸã¯ãã£ãã·ã¥ããã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒã³ã³ãã€ã«å¯Ÿè±¡ããå®å
šã«é€å€ïŒDiscarded StatementïŒããããã®åå²å
ã«å«ãŸããåäžé©åã³ãŒãããã£ãŠãæ§æãšã©ãŒã«ãªããããã€ããªãçæãããªã
if constexpr ã¯ã³ã³ãã€ã«æåå²ã§ããæ¡ä»¶ãåœãšãªã£ããã©ã³ãã¯ã³ã³ãã€ã©ã«ãã£ãŠç Žæ£ããããã³ãã¬ãŒãåŒæ°ã«å¯ŸããŠäžæ£ãªã¡ã³ãåŒã³åºãçãå«ãŸããŠããŠããšã©ãŒã«ãªãããã³ãŒãçæãäžåè¡ãããŸããã
Q2. C++17ã®ãæ§é åæçžïŒStructured BindingsïŒãã®æ©èœãšããŠæ£ãã説æã¯ã©ãã§ããïŒ
1. æ§é äœãã¯ã©ã¹ã®ã¡ã³ã倿°ããã¹ãŠ private ã«åŒ·å¶ããæ©èœ 2. auto [x, y, z] = tupleOrStruct; ã®ããã«ãæ§é äœã®ã¡ã³ããé
åãstd::pair/std::tuple ã®èŠçŽ ã1è¡ã§åè§£ããŠå倿°ã«æçžã§ããæ©èœ 3. ã¯ã©ã¹ã®ç¶æ¿é¢ä¿ãã³ã³ãã€ã«æã«çµåããæ©èœ 4. æ§é äœã®ã¡ã¢ãªé
眮ã1ãã€ãåäœã«ãããã³ã°ããæ©èœ
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒauto [x, y, z] = tupleOrStruct; ã®ããã«ãæ§é äœã®ã¡ã³ããé
åãstd::pair/std::tuple ã®èŠçŽ ã1è¡ã§åè§£ããŠå倿°ã«æçžã§ããæ©èœ
æ§é åæçžïŒauto [a, b, ...] = expr;ïŒã«ãããã¿ãã«ããã¢ãæ§é äœã®ã¡ã³ããçŽæ¥å¥ã
ã®å€æ°ãšããŠåãåãããšãã§ããããã«ãªããstd::tie ã .first/.second ãªã©ã®åé·ãªèšè¿°ãäžèŠã«ãªããŸããã
Q3. C++17ã®ããã©ãŒã«ãåŒïŒFold ExpressionsïŒãã®äž»ãªç®çã¯äœã§ããïŒ
1. é·ã颿°ããšãã£ã¿äžã§æããããã§é衚瀺ã«ããæ©èœ 2. å¯å€åŒæ°ãã³ãã¬ãŒãïŒãã©ã¡ãŒã¿ããã¯ïŒã«å¯Ÿããäºé
æŒç®ïŒå ç®ãåºåãªã©ïŒããååž°é¢æ°ãæžããã« (... + args) ã®ããã«1è¡ã§å±éã»éçŽãããã 3. ã³ã³ãã€ã«æã«ã³ãŒããé£èªåã»å§çž®ãããã 4. ãã«ãã¹ã¬ããåŠçãèªåçã«ãã©ãŒã«ãïŒåæµïŒããããã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒå¯å€åŒæ°ãã³ãã¬ãŒãïŒãã©ã¡ãŒã¿ããã¯ïŒã«å¯Ÿããäºé
æŒç®ïŒå ç®ãåºåãªã©ïŒããååž°é¢æ°ãæžããã« (... + args) ã®ããã«1è¡ã§å±éã»éçŽãããã
ãã©ãŒã«ãåŒã¯å¯å€åŒæ°ãã³ãã¬ãŒãã®åŒæ°ãªã¹ãïŒargs...ïŒã«å¯ŸããæŒç®ïŒ+, *, <<, && ãªã©ïŒããååž°åŒã³åºããã³ãã¬ãŒãã®å®çŸ©ãªãã§ `(... + args)` ã®ããã«ç°¡æœã«èšè¿°ã§ããC++17ã®æ°æ©èœã§ãã
ð»ââïž ã·ãã¯ãC++ã©ã ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ã·ã¹ãã
ãã©ãŠã¶ã§JavaScriptãæå¹ã«ãããšããã©ãŠã¶å
ã€ã³ããŒããŒã²ãŒã ãšãã¥ã¬ãŒã¿ãã¡ã¢ãªãããå¯èŠåãUMLã¯ã©ã¹å³ã察話å解説ãç解床ã¯ã€ãºãèµ·åããŸãã
ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ãéå§ãã â