Boost.Optional Must Go - 野良C++erの雑記帳
Boost.Optional Must Go (2) - 野良C++erの雑記帳
æè¿ãä½åãã«åãã¦ã Boost.Optional ã«ã¤ãã¦ãï¼ç´°ããï¼ä¸æºãæ¥è¨ã«æ¸ãã¦ãã¾ããã
ããã¯å¥ã« Boost.Optional ãå«ãã ããä¸æºãæ¸ãã訳ã§ã¯ãªããããã ãã®éã
Boost.Optional ã便å©ãªåãéã«ä¸æºç¹ãç®ç«ã¤ã®ã§æ¸ãã¦ããããã§ããã
ããèãããã Boost.Optional ã®ä¾¿å©ãããçºã¾ã£ãè¨äºã§æ¸ãã¦ããªããªã¼ã
ã¨ãããæãè³ã£ãã®ã§ããã®è¾ºã§ Boost.Optional ãå¾¹åºçã«æ¨å¥¨ããè¨äºã§ãæ¸ãã¦ã¿ããããªã
ã¨ããããã§ãããããæ¢åºãªãã¿ã°ããã§ãããæè§ãªã®ã§æ¸ãã¦ã¿ããã¨ã«ãã¾ãããã
åé ã«æãã以å¤ã§åèã«ãªããããªè¨äºã¯ããã®è¾ºã§ããããï¼
C++ で Maybe モナド - 野良C++erの雑記帳
Boost.Optional と Boost.InPlaceFactory で初期化遅延 - 野良C++erの雑記帳
とりあえずメモリを確保→後からオブジェクトを構築するテク - 野良C++erの雑記帳
ããã§ã¯ãé·æã«ãªãããããã¾ãããããä»ãåãããã ããã¨å¹¸ãã
ãã®è¨äºã¯ãæ°ãã« Boost.Optional ã®é
åãããã次第ã追è¨ãã¦ããäºå®ã¯æªå®ã§ãã
0. Boost.Optional äºå§ã
ã¾ã Boost.Optional ãç¥ããªã人ã«ãæçã«è§£èª¬ã
å
¬å¼ï¼ http://www.boost.org/doc/libs/1_43_0/libs/optional/index.html
boost::optional
使ãæ¹ã¯å
¨ä½çã«ãã¤ã³ã¿ã模ãããã®ã«ãªã£ã¦ããã
boost::optional<int> x = 23; // æ§ç¯ã¯ãã¤ã³ã¿ã¨éãã T ããæé»å¤æã§ãã // 使ãæ¹ã¯ãã¤ã³ã¿ã¨åãã§ã if( x ) // if ã§æå¹ï¼ç¡å¹ããã§ãã¯ãã¦ã { std::cout << *x << std::endl; // æå¹ãªã * ã§å®éã®å¤ãåãåºãã } x = boost::none; // x ã«å¯¾ãã¦ãç¡å¹ç¶æ ããè¨å® assert( !x ); boost::optional<int> y = 42; // int i = y; // ãã¡ãå¤ãåãåºãæã«ã¯ * ã使ãã x = y; // optional å士ãªãæ®éã«ä»£å ¥åºæ¥ãï¼å½ç¶ï¼ // y ãæå¹ã¨åãã£ã¦ããªãã x = *y; ã¨æ¸ãã¦ãããï¼ããåé·ï¼ã
ãããªæãã§ä½¿ãã¾ãã
ãã¤ã³ã¿ã¨éãç¹ã¯ãå¤ã®è«çã§åãç¹ã§ãï¼
boost::optional<int> x = 23, y; y = x; // y ã« x ãä»£å ¥ã㦠*x = 42; // x ã®ä¸èº«ãå¤ãã¦ã assert( *y == 23 ); // y ã®ä¸èº«ã¯å¤ãããªã
ãã®ããã«ãå
¨ã¦ã® boost::optional
ããããè¸ã¾ãã¦ã Boost.Optional ã®ä½¿ãéãè¦ã¦ããã¾ãããã
1. ã失æãããããããªããé¢æ°ã®æ»ãå¤ã¨ãã¦ä½¿ã Boost.Optional
ã¾ã Boost.Optional ã®å½¹å²ã¨ãã¦ã®åºæ¬ã誰ã§ãç¥ã£ã¦ãã®ãããã
boost::optional
é¢æ°ã«å¤±æããçµæã表ãå¤ã¨ãã¦ä½¿ãããã¨ããèãæ¹ã§ã
ããã¯æè¬ Haskell ã® Maybe ã¢ããã¨åãå½¹å²ã§ããã
Haskell ã® Maybe ã¢ããã¨åæ§ã極ãã¦å¼·åãªèãæ¹ã§ãã
ç¡è«ãC++ã§ã¯ä»ã«ããé¢æ°ã®å¤±æãã表ç¾ããæ¹æ³ã¯ããããã§ããã
Boost.Optional ã使ãã¡ãªããã¯ãã¨ã«ããæ±ç¨æ§ã«å¯ãã§ããç¹ã
C++ã§ãé¢æ°ã®å¤±æãã表ãæ¹æ³ã¨ãã¦ã¯ãä¾å¤æ©æ§ãªã©ãããããã§ããã
C++ã«ãããä¾å¤å¦çã¨ããã®ã¯ãåºæ¬çã«ã³ã¹ããæããã®ã§ã
é¢æ°ã®å¤±æã
ãããç¨ã«ããèµ·ããªãããããã¯ãäºåã®ãã§ãã¯ã§åãé¤ããã
å ´åã«ã®ã¿ä½¿ãã¹ãã§ããã
é »ç¹ã«å¤±æãããªãã°ãå¥ã®æ段ã模索ããæ¹ãè¯ãå ´åãæ®ã©ã§ãã
è¦ããã«ãä¾å¤ã¯ ããã¾ã§ãä¾å¤çãªäºæ
ãã«å¯¾å¦ããçºã®ãã®ãªã®ã§ãæ°è»½ã«ã¯ä½¿ããªãã®ã§ãã
ä¾å¤å¦çã使ããªãå ´åã¯ãæ»ãå¤ã«ãã£ã¦æå¦ãå¤å¥ãããã¨ã«ãªãã¾ããã
ãã®å ´åã
- ãæ»ãå¤ã¯ï¼ã¹ãã¼ãï¼ãã¤ã³ã¿ã«ãã¦ã NULL ã ã£ãã失æã¨ããæå³ã«ããã
- ãæ£å¸¸ãªçµæã®æã¤å¶ç´ï¼ä¾ãã°éè² ã®å¤ã«ãªãï¼ãå©ç¨ããæ£å¸¸ã§ãªãçµæï¼ä¾ãã°è² ã®å¤ï¼ãè¿ããå ´åã«ã¯å¤±æã¨ããæå³ã«ããã
- ãé¢æ°ã®çµæã¯åç §ï¼or ãã¤ã³ã¿ï¼å¼æ°çµç±ã§è¿ããæ»ãå¤ã§æå¦ã示ãã
ãªã©ã®æ¹æ³ããç¶æ³ã«å¿ãã¦ä½¿ãåãããã¨ã«ãªãã¾ãã
ãããããããã®æ¹æ³ã«ã¯ãã©ããä¸é·ä¸çãã£ã¦ã
- æ»ãå¤ãï¼ã¹ãã¼ãï¼ãã¤ã³ã¿ã«ããå ´åã¯ãï¼ã©ããï¼ãã¹ã§ãã£ã¦ãï¼ä¸æãªãã¸ã§ã¯ããä½ã£ã¦è¿ãããå ´åã«ãï¼å ¨ã¦ã®ãã¹ã§ï¼åçã¡ã¢ãªç¢ºä¿ãå¿ è¦ã«ãªããçãã¤ã³ã¿ã®å ´åã«ã¯ããã®åç §å ã解æ¾ããã¹ããå¦ãããããã¥ã¡ã³ããèªãã§ç¢ºèªããªããã°ãããªãã
- æ£å¸¸ãªçµæã®æã¤å¶ç´ã使ã£ãå ´åã«ã¯ãæ»ãå¤ã«å¶ç´æ¡ä»¶ãç¡ãå ´åã«å°ããã¾ããæ£ãã使ãã«ã¯ããã¥ã¡ã³ãããã£ããèªã¾ãªããã°ãããªãããã¾ãå¶ç´æ¡ä»¶ãå¤ãããããªä»æ§å¤æ´ãè¡ããªãã
- åç §å¼æ°çµç±ã§çµæãè¿ããæ»ãå¤ã¯æå¦ã示ãå ´åãé¢æ°ãå¼ã³åºãåã«ãäºã çµæãæ ¼ç´ããå¤æ°ãç¨æããªããã°ãããªããçµæãåãåãå¤æ°ãçµã¿è¾¼ã¿åã§ãªãå ´åã«ã¯ åæåããåãä½è¨ãªã³ã¹ãã«ãªãããä¸è¬ã«å ¨ã¦ã®åã default constructible ã§ããã¨ã¯éããªãã®ã§ãã³ãã¬ã¼ãã«ãã«ããããçµæãæ ¼ç´ããå¤æ°ã const ã«ãããã¨ãåºæ¥ç¡ãããã³ãã¬ã¼ãã const ã使ããªãå ´å*1ã§ãã£ã¦ããæ»ãå¤ããã§ãã¯ããªãã¨ããæ æ ¢ãçããã
ã¨ã使ãåããã®ãæ£ç´é¢åã§ããããªã·ã¼ã«ãã¦ä½¿ãåããããã¨ããªã£ãããå°æ´ã
ããã§ã Boost.Optional ã®åºçªã§ãã
Boost.Optional ã¯ãæ»ãå¤ãï¼ã¹ãã¼ãï¼ãã¤ã³ã¿ã¨ãã¦è¿ããã¨ããæ¦ç¥ã®çºå±å½¢ã§ããã
æåã«ç´¹ä»ããéãããã¤ã³ã¿ã¨åæ§ã®æ§æã§ä½¿ãã¾ãã
ï¼ã¹ãã¼ãï¼ãã¤ã³ã¿ã¨éãç¹ã¯ãåçã¡ã¢ãªç¢ºä¿ãè¡ããªããã¨ããç¹ã§ãã
ããã«ãããåç´ã«ãè¡ãå¦çã®éãæ¸ããã¨ããã ãã§ãªãã
åç確ä¿ãè¡ãå ´åã«æ¯ã¹ãã³ã³ãã¤ã©ã«ããæé©åã妨ããè¦å ãå°ãªããªãã¾ãã
御è¨ã¯ãããããã«ãã¦ãå®éã«ä½¿ã£ã¦ã¿ã¾ãããã
ä¾ã¨ãã¦ãstd::getline ã boost::lexical_cast ããBoost.Optionalã§æ¸ãæãã¦ã¿ããã¨ã«ãã¾ãã
#include <boost/optional.hpp> // é¢æ°ä¾ï¼ï¼ std::getline ã optional æååã§è¿ãããã«ãã // çµæãåãåãããã®ä¸æå¤æ°ãä½ãå¿ è¦ããªããªã #include <iostream> inline boost::optional<std::string> get_line( std::istream & is ) { std::string temp; if( std::getline( is, temp ) ) { return temp; } else { return boost::none; } } // é¢æ°ä¾ï¼ï¼ boost::lexical_cast ã optional ã«ãã // 失æããå¯è½æ§ãé«ãå ´åã«ãä¾å¤ã§ã¯ãªã if ã§æ±ããã®ã¯ä¾¿å©ã #include <boost/lexical_cast.hpp> template<typename Target, typename Source> inline boost::optional<Target> lexical_cast_opt( Source const& src ) { try { return boost::lexical_cast<Target>( src ); } catch( boost::bad_lexical_cast& ) { return boost::none; } } #include <boost/format.hpp> #include <boost/algorithm/string.hpp> // for trim int main() { // 使ç¨ä¾ // å ¥åãäºåã«ãã¦åºåããããã°ã©ã // å ¥åãåã£ã¦ãã¦ãå¤æ°ã«æç¸ if( auto input_ = get_line( std::cin ) ) { // ãã¡ãã¡ * ã§åç §ããã®ã¯é¢åãªã®ã§ãäºãåç §ãå¤ãã¦ãã std::string& input = *input_; // lexical_cast ã¯ç©ºç½ãç¡è¦ããªãã®ã§ãäºã trim ãã¦ãã boost::algorithm::trim( input ); // ãã£ãã¯é const ã§åããããæ®é㯠const ã§åããæ¹ããèªç¶ã if( auto const value = lexical_cast_opt<double>( input ) ) { // å¦çå 容ãçããªã * ã使ã£ã¦æ¸ãæ¹ãç°¡æ½ã std::cout << *value * 2 << std::endl; } else { std::cout << boost::format("'%1%' is not a number.\n") % input; } } else { std::cout << "no input.\n"; } }
ã©ãã§ããããã
ä¸è¬ã« boost::optional
ã if ã®æ¡ä»¶é¨ã§å¤æ°ã宣è¨ãã¦çµæãåãåãããããæå¹ãªãã
ã¨ããå¦çãæ¸ãã¾ãã
ããã¯æ
£ããªã人ã«ã¯å¥å¦ã«æããããããã¾ãããããã£ãã¨ããC++ã®ã³ã¼ãã§ããã
æ
£ãã¦ãã¾ãã°é常ã«å¼·åãªè¡¨ç¾åãæã¡ã¾ãã *2
ãã®æ¸ãæ¹ã¯ãä¸è¬ã«ããã¤ã³ã¿ã§æ»ãå¤ãå¾ãå ´åã«ã使ãããã¨ãããã¨ã« ãæ°ã¥ãã§ããããã
ããã§ããæ»ãå¤ã auto ã§åã㦠if ã§ãã§ãã¯ãã if å
é¨ã§ã¯ * ã§ã¢ã¯ã»ã¹ãã¨ããæ§æã¯ã
å®éã®æ»ãå¤ã optional ãªã®ããã¤ã³ã¿ãªã®ãã«ãã£ã¦ãæ¸ãæ¹ãå¤ããå¿
è¦ããªãã®ã§ãã
ããã¯æ¥µãã¦å¼·åã§ãã
ãªããªããæ¸ãæ¹ãåããªãããã³ãã¬ã¼ãã使ããã¨ãåºæ¥ãããã§ãã
ã¨ããã¨ãä»®ã«ãæ»ãå¤ã®æ¡ä»¶ãå©ç¨ãã¦é¢æ°ã®æå¦ã示ããã¨ããæ¹éãæ¡ã£ãå ´åã§ãã
æ»ãå¤ã®åãã©ããããã¯ã©ã¹ãä½ããé©å㪠operator bool 㨠operator * ãå®ç¾©ãããã¨ã§ã
optional ããã¤ã³ã¿ã¨åæ§ã®æ¸ãæ¹ãæä¾ããã°ã
ãããã¾ããã³ãã¬ã¼ãã使ã£ã¦æ¸ã表ããã¨ãåºæ¥ããã¨ãããã¨ã«ãªãã¾ãã
ã¤ã¾ãããã®ã if ã§ãã§ãã¯ãã * ã§åãåºããã¨ããæ¸ãæ¹ã¯ã
失æããå¯è½æ§ã®æãå¦çãè¡ãå ´åã®ãçµ±ä¸çãªæ¸ãæ¹ãã§ããã
Boost.Optional ããã¤ã³ã¿ã¨åãæ§æã«ãªã£ã¦ãããã¨ã«ããæ大ã®ã¡ãªããã§ããã
Boost.Optional ã®ç´ æ´ããããæã端çã«ç¤ºãã¦ããã¨ãåã¯èãã¾ãã
ãã®ãçµ±ä¸çãªæ¸ãæ¹ãã¯ãåã«ããã³ãã¬ã¼ãã§çµ±ä¸çã«æ¸ãããã¨ããã ãã§ãªãã
ããã¦ããããã®å¦çã楽ã«æ¸ãããããªãã¯ã*3ãçã¿åºããããã¨ãããã¨ãååã«èãããã¾ããã
å°æ¥çã«ã¯ãæ¡å¼µãã㦠C++ ä¸ã§ãã¿ã¼ã³ãããã³ã°ãå®ç¾ããããã®åå°ã¨ãªããå¯è½æ§ãããã¾ãã
ãããã¦å¤¢ã¯åºãã£ã¦ããã®ã§ãã
ãªã«ãããåç´ã«ãçµ±ä¸çã«æ¸ããæ¹ãã«ãã³ãããã¨ããã®ãããã¾ãããã
ã¨ã¯ããå®ã®ã¨ããã Boost.Optional ã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã¯ã Haskell ã«æ¯ã¹ã¦åé·ã§ãã
Haskell ãªããã¢ããã使ããã¨ã§ã失æãããããããªãå¦çã綺éºã«ä¸¦ã¹ã¦æ¸ããã®ã§ããã
Boost.Optional ã«ã¯ãã®è¾ºãã®ãµãã¼ããå°ãªãããã®è¾ºããå°ãä¸æºã ã£ãããã¾ãã
ããã¯ãä»å¾ã®çºå±ã«æå¾
ããã¨ãããã¨ã§ã
2. ä»»æã®ã¿ã¤ãã³ã°ã§ãªãã¸ã§ã¯ããæ§ç¯ï¼ç ´æ£ã§ããããã¡ã¢ãªç®¡çã¯ã©ã¹ãã¨ãã¦ã® Boost.Optional
ãã¦ããããããæ¬é¡ã§ãã
Boost.Optional ã¯ãè«ççã«ã¯ã T ã«ç¡å¹å¤ã追å ãããã¨ãããããã ãã®ç©ã§ãã
ããã§ãååã«å¼·åãªã®ã¯åã®ç« ã§æããéãã§ããã C++ çã«ã¯ãããã«å£ããå¼·åãªãããã²ã¨ã¤ã®å´é¢ãããã¾ãã
ããããæ±ç¨çãªã¡ã¢ãªç®¡çã¯ã©ã¹ãã¨ãã¦ã® Boost.Optional ã§ã
Boost.Optional ã使ããã¨ã§ããªãã¸ã§ã¯ãã®å¯¿å½ç®¡çãããã£ã¨æè»ã«ããã¤ä½ã³ã¹ãã§è¡ããã¨ãã§ããã®ã§ãã
ã¨è¨ã£ã¦ããããã«ã¯ããã¨ããªãããããã¾ããã
ããã§ãå
·ä½çãªä¾ãæãã¦ã¿ã¾ãããã
å¤ã®ãåæç¸ããåºæ¥ãã¯ã©ã¹ã¨ãã¦ã® Boost.Optional
Boost.Optional ã¯ãä»»æã® T ã«å¯¾ãã¦ãå¤ã®ãåæç¸ããå¯è½ã«ãã¾ãã
ãåæç¸ãã¨ããã¨å°ãä»°ã
ããæãã§ãããè¦ã¯ãå代å
¥ãã§ãã
ãããããå代å
¥ãã¨è¨ã£ã¦ããå®éã«ã代å
¥ããã¦ããããã§ã¯ããã¾ããã
å
·ä½çã«è¨ããªãããã operator= ãå®ç¾©ããã¦ãã¨ãã¦ããããã¯å¼ã°ãã¾ããã*4
boost::optional
T åã®ãªãã¸ã§ã¯ãããä½ãç´ãããã¨ãåºæ¥ãã®ã§ãã
ããè¨ãã¨ãããããã©ãããã®ãã¨æãããããã¾ããã
ã®ã§ããã㧠Boost.Optional ã®å®è£
ã«ã¤ãã¦è»½ã触ãã¦ããã¾ããèå³ã®ç¡ãæ¹ã¯ã¹ã«ã¼ãã¦ä¸ããã
boost::optional
- T åãæ ¼ç´åºæ¥ã大ããï¼ã¢ã©ã¤ã¡ã³ãã確ä¿ãããã¡ã¢ãªé å
- ããã®ã¡ã¢ãªé åã«å®éã«ãªãã¸ã§ã¯ããæ§ç¯ããã¦ããããã示ããã©ã°å¤æ°
ãã®ï¼ã¤ãããªãã¾ãã
ãã©ã°ãç«ã£ã¦ããå ´åãã¡ã¢ãªé åã«ã¯ãªãã¸ã§ã¯ããå®éã«æ§ç¯ããã¦ããã®ã§ã
ç¡å¹ç¶æ
ã«é·ç§»ããæãããã¹ãã©ã¯ã¿ã®å¼ã³åºãæã¯ããã£ã¡ãã¨ä¸èº«ãç ´æ£ãã¦ããå¿
è¦ãããã¾ãã
ä¸æ¹ããã©ã°ãç«ã£ã¦ããªãå ´åãã¡ã¢ãªé åã¯ãã ã®æªåæåã¡ã¢ãªã§ãã
ããã大åæã¨ãã¦ãç¶æ³ã«å¿ãã¦ã
ãã¡ã¢ãªé åã«ãªãã¸ã§ã¯ããæ§ç¯ãããã©ã°ãç«ã¦ãããæ§ç¯ããããªãã¸ã§ã¯ããç ´æ£ãããã©ã°ãåãã
ã¨ããå¦çãè¡ã£ã¦ããã®ãã Boost.Optional ã®å®è£
ã«ãªãã¾ãã
ãããè¸ã¾ããä¸ã§ã Boost.Optional ã«å¯¾ãã¦å¤ã代å
¥ããå ´åã®å¦çãèããã¨
- ãã©ã°ãç«ã£ã¦ãããªããæ¢ã«ãªãã¸ã§ã¯ããæ§ç¯ããã¦ããã®ã§ããªãã¸ã§ã¯ããç ´æ£ãã¦ãã©ã°ãåã
- ç¡å¹ç¶æ ã®ã¡ã¢ãªé åã«å¯¾ãã¦ãªãã¸ã§ã¯ããæ§ç¯ããæåããããã©ã°ãç«ã¦ã
ã¨ããå¦çãè¡ãã°ãç´æ¥çãªä»£å ¥æä½ãè¡ãªããã¨ãªããåä»£å ¥ãå®è£ ãããã¨ãåºæ¥ãã®ã§ãã
ãã¦ãå®è£
ã®è©±ã¯ããã¾ã§ã«ãã¦ãå代å
¥ãã¨ãããã¨ã«ã¤ãã¦ããããèãã¦ã¿ã¾ããããã
ãå¤æ°ãå代å
¥ã§ãããã¨èãã¨ããªãã¨ãªãã¹ã´ããã«æããããããã¾ãããã
å代å
¥ããã¨è¨ããã¨ã¯ãããã ããã°ã®åå ãå¢ãããã¨ãããã¨ã§ãããã¾ãã
ç¹ã«ãå代å
¥ããããã¨ãæ³å®ããã¦ãªãåã«å¯¾ãã¦ãæ¬ä¼¼çã«å代å
¥ãå®ç¾ããå ´åã
ã³ã¼ãã¬ãã«ã§ã¯æ確ã«æ§æãåºå¥ãããã®ã§åé¡ã¯ãªãã¨ããã°ãªãã®ã§ããã
ã³ã¼ããæ¸ã人ã«ãã£ã¦ã¯ãã¡ãã£ã¨æ··ä¹±ãã¦ãã¾ããããªãã¨ããããããããã¾ããã
ã§ãããç¾å®ã¨ãã¦ã C++ ã¨ããè¨èªã¯ãå¤æ°ã¸ã®å代å
¥ãå¯è½ãªè¨èªã§ãã
ããã«ãã£ã¦å¤±ãããç©ã¯å¤§ããã§ãããå¾ãããç©ããã¾ã大ããã
æ¬æ¥ãªãã°ä»£å
¥æä½ãåºæ¥ç¡ãåã«å¯¾ãã¦ã代å
¥æä½ãå¯è½ã«ããã
ãã®ãã¨ã§å¾ãããå©çã¯ã決ãã¦å°ãªããªãçã§ãã
ãªã®ã§ã Boost.Optional ã使ããªãã Boost.Optional ããåæç¸å¯è½ã§ãããã¨ããç¹ã¯ã
ç¥ã£ã¦ãã¦æã¯ãªãäºå®ã ã¨æãã®ã§ãããã§ç´¹ä»ãããã¨ã«ãã¾ããã
ã¨ã話ãå°ãèéã«ããã¾ããã
ã§ã¯ããã®ãåæç¸å¯è½ã§ãããã¨ããç¹ãæ´»ããã¦ãå
·ä½çã«ãã©ã®ãããªã³ã¼ããæ¸ãããã
ããã§å
·ä½çã«ãå代å
¥ã§ããªããåãèããå ´åã代表çãªãã®ã¯ãconstå¤æ°ãã¨ãåç
§ãã§ãã
ããããã¡ã³ãã«ãã¤ã¯ã©ã¹ããå代å
¥ã§ããªããåã¨ãªãã¾ããããããã¯ãããã®ç°¡åãªå¿ç¨ã§ãã
ãã£ã¦ã代表çãªä¾ã¨ãã¦ããconstãã¨ãåç
§ãã«å¯¾ãã optional ãè¦ã¦ãããã¨ã«ãã¾ãããã
boost::optional
ã¾ããå代å
¥ã§ããªããåã®æåã®ä¾ã const ãªå¤ã«å¯¾ãã optional ããè¦ã¦ããã¾ãããã
boost::optional
// const ã¸ã® optional ã«ã¤ã㦠boost::optional<int const> x = 1; std::cout << *x << std::endl; // OK. éç ´å£çãªæä½ã¯ä»»æã«è¡ãã ++(*x); // NG. ç ´å£çãªæä½ã¯è¡ããªã x = 2; // OK. åä»£å ¥ã§ãã *x = 3; // ããã¯ãã¡ãããã¾ã§ optional ã«å¯¾ããåä»£å ¥ã®ã¿ãåãä»ãã // åèã¾ã§ã« const 㪠optional ãç´¹ä» boost::optional<int> const y = 1; std::cout << *y << std::endl; // OK. éç ´å£çãªæä½ã¯ä»»æã«è¡ãã ++(*y); // NG. ä¸èº«ã«å¯¾ãã¦ãç ´å£çãªæä½ã¯è¡ããªãï¼æ¨ç§»çï¼ y = 2; // NG. åä»£å ¥ãåºæ¥ç¡ã *y = 3; // å½ç¶ãããããã¡ã
*x = 3;
ã¨ããã³ã¼ããã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãç¹ã«æ³¨ç®ãã¦ä¸ããã
Boost.Optional ã¯ã optional èªèº«ã«å¯¾ããæä½ã¨ãä¸èº«ã«å¯¾ããæä½ããæ確ã«åºå¥ãã¾ãã
ãã ãåºå¥ã¯ãããã®ã®ã Boost.Optional ã¯åç
§ï¼ãã¤ã³ã¿ï¼ã§ã¯ãªãå¤ã®è«çã§åãã®ã§ã
é常㯠optional ã«å¯¾ããæä½ã¯ãä¸èº«ã«å¯¾ãã¦ãåæ§ã«åãã¾ãã
ãã代å
¥æä½ã¯éãã¾ãã
ãã£ãã触ããéãã Boost.Optional ã®ä»£å
¥æä½ã¯ã
- ã¾ããããã¾ã§å ¥ã£ã¦ãããã®ãç ´æ£ãã¦ã空ç¶æ ã«ãã
- ãããããå³è¾ºã®å¤ãå ã«ã³ã³ã¹ãã©ã¯ã¿ãå¼ã³åºããä¸èº«ãåæ§ç¯ãã
ã¨ããäºæ®µéã§å¦çãããã®ã§ãåé¡ãªãåä»£å ¥ã§ããã®ã§ãã
ãã£ã¨ããåã«å代å
¥ããããã ããªããå¥ã« optional ã§ãªãã¦ãããã®ã§ã¯ãã¨æãããããã¾ããã
ã¤ã¾ããç¡å¹ç¶æ
ãã¨ããä½è¨ãªç¶æ
ãæããªããç´ç²ã«ãå代å
¥å¯è½ããªã¯ã©ã¹ãä½ããã®ã§ã¯ãã¨ã
çµè«ããè¨ãã¨ãä¸è¬ã®å T ã«å¯¾ãã¦ããããããã¨ã¯ä¸å¯è½ã§ãã
çç±ã¯ããå代å
¥ãããæã®ã³ã³ã¹ãã©ã¯ã¿å¼ã³åºãã§ãä¾å¤ãæããããå¯è½æ§ãæãããã
ãã®å ´åãä¾å¤å®å
¨ã®å¼·ãä¿è¨¼ãæºããã®ã¯ãä¸å¯è½ã§ã¯ãªãã§ãããé常ã«é¢åã§ããã
ãããªãã°ã空ã®ç¶æ
ãåãå
¥ãããããã¨ããä¸ã§ãä¾å¤å®å
¨ã«é¢ãã¦ã¯åºæ¬çãªä¿è¨¼ã®ã¿ãè¡ãªãã®ããçã«ããªã£ã¦ããã®ã§ãã*5
â¦ã¨ãå°ã
è±ç·ãã¦ãã¾ãã¾ãããæ®éã«ä½¿ãåã«ã¯ããããã®å®è£
ãæ°ã«ããå¿
è¦ã¯ããã¾ããã
è¦ããã«ãå®å
¨æ§ã®ããã« const ã«ããããã©ãã§ãå代å
¥ã¯ããããã£ã¦ããç¶æ³ã«ããã¦ã
ãããå®ç¾ããæå¹ãªæ¹æ³ã®ãã¡ã®ä¸ã¤ã boost::optional
ããã©ã¼ãã³ã¹ãèããã¨ä»ã®é¸æè¢ãè¯ãå ´åãå¤ãã§ãããä½ããæ軽ã§ä¾å¤å®å
¨ãªã®ã§ã
æåã®è©¦é¨çãªå®è£
ãªã©ã«ç¨ããåã«ã¯ãåäºåãªå¼·ããçºæ®ãã¾ããæ¯éã¨ã使ã£ã¦ã¿ã¾ãããã
è¨æ£ï¼ boost::optional
http://d.hatena.ne.jp/gintenlabo/20100905/1283706950
boost::optional
次ã«ããå代å
¥ã§ããªããåã®ããä¸ã¤ã®ä»£è¡¨ä¾ãåç
§ã«å¯¾ãã optional ãè¦ã¦ã¿ã¾ãã
ããã¯ãã¡ã¢ãªç®¡çã¨ããç¹ããã¯å°ãå¤ãã¾ããã
Boost.Optional ã®ä¸ã§ããç¹ã«ç°è³ªã§ãç¹ã«éè¦ãªæ¦å¿µãªã®ã§ããã£ãã触ãã¦ããããã§ãã
ç¹°ãè¿ãã«ãªãã¾ããã boost::optional
ããã«ã T ã«å¯¾ãã¦ä»£å
¥æä½ãè¡ããã¨ãªããå¤ã®åæç¸ãå¯è½ã«ããã®ã§ããã
ã¤ã¾ã boost::optional
å®éã«ä½¿ã£ã¦ã¿ã¾ãããã
int i = 23, j = 42; boost::optional<int&> x = i; std::cout << *x << std::endl; // x ã®åç §å ã®å¤ã表示 ++(*x); // x ã®åç §å ã®å¤ãã¤ã³ã¯ãªã¡ã³ã std::cout << i << std::endl; // 24 x = j; // åç §å ãå¤ãã ++(*x); // å¤æ´ãããåç §å j ã®å¤ãã¤ã³ã¯ãªã¡ã³ã std::cout << i << std::endl; // 24 std::cout << j << std::endl; // 43 x = boost::none; // x ããä½ãæã示ãã¦ããªããç¶æ ã«ãã assert( !x ); // x ã¯ç¡å¹åç § ++(*x); // æªå®ç¾©åä½ï¼é常㯠assert ã«å¼ã£ãããï¼
â¦ãæ°ã¥ãã§ããããã
ããã¯è¦ããã«ãçãã¤ã³ã¿ãã®ãã®ã§ãã
å®éã使ç¨ä¾ãè¦ãã¨ã
å¤æ°ã®è¨å®ã®é¨åã¯ãçãã¤ã³ã¿ã¨ã¯éãæ§æã使ã£ã¦ãã¾ããã
ãã以å¤ã®å ´é¢ã§ã¯ãåºæ¬çã«çãã¤ã³ã¿ã¨åãããã«æ¸ãã¦ãããã¨ãåããã¾ãã
ã¨è¨ãã¨ã
ããªãã ãçãã¤ã³ã¿ã¨åããªããçãã¤ã³ã¿ã使ãã°ãããããªããã
ã¨æãããããã¾ããã
ããããåã¯ããã¯æãã¾ããã
ãªããªãã°ãçãã¤ã³ã¿ã¯ããã£ãããã¹ã®æ¸©åºã ããã§ãã
int* p; // åæåãã¦ãªããã¤ã³ã¿ã¯ NULL ã¨ã¯éããªãã if( p ){ /* ... */ } // if ãã§ãã¯ããããæãã¦ãã¾ããæ½å¨çãªå±éºãããã boost::optional<int&> x; // ä¸æ¹ããã¡ãã¯å¸¸ã« none ã§ããã if( x ){ /* ... */ } // ããã¯æ確ã«å®è¡ãããªãã struct hoge { hoge* operator&() { return (hoge*)666; } // operator& ãå¤éå®ç¾©ããã¦ãï¼ } h; hoge* p2 = &h; // NG. boost::addressof ã使ãã¹ãã boost::optional<hoge&> x2 = h; // OK. delete p2; // ãã£ãã delete ãã¦ãã¾ãï¼ï¼ï¼ã³ã³ãã¤ã«ã¯éããåä½ã¯æªå®ç¾©ãï¼ delete x2; // ã³ã³ãã¤ã«ã¨ã©ã¼ã
ã©ãã§ãããã
確ãã«ããããã®ãã£ãããã¹ã¯ãããæ¹ãæªããã¨ããåæ©çãªãã®ã°ããã
operator& ã®å¤éå®ç¾©ã¨ããã¾ãã«ããããªã¯ã©ã¹ãæ¸ãæ¹ãæªããã§ãã
ã§ãã人éãªã®ã§ããã£ãããã¹ã¯ä»ãç©ã
ã¡ãã£ã¨ãã工夫㧠ãã£ãããã¹ãææ¢ã§ãããªããããã«è¶ãããã¨ã¯ãªãã§ããã
ä½ããã boost::optional
ãããã¯ããã¾ã§ãç¡å¹å¤ãåãã¦å代å
¥å¯è½ãªããåç
§ãã§ããã
ã¨ããæå³ããæ確ã«ã§ããã®ã§ãã
å®ã®ã¨ãããæ¨æºã¨æºæ¨æºãåããã¦ãã
ãã®æã®ãåæç¸ã§ããåç
§å¤æ°ãã£ã¦ããã®ã¯ãå®ã¯ boost::optional
çãã¤ã³ã¿ T* ã«ããã® boost::optional
ãããã®ãã¡ãçãã¤ã³ã¿ã¯ãåç
§ä»¥å¤ã«ã使ããããå®å
¨æ§ãä½ããã¨ããå¼±ç¹ãããã
reference_wrapper ã¯ãç¡å¹åç
§ãåããã¨ãåºæ¥ãªããã¨ããå¼±ç¹ãããããã
boost::optional
ã«ãé¢ããããç¾ç¶ã boost::optional
ããã¯ãåç´ã«ãæåã§ãªããã¨ããä»ã«ã
Boost.Optional Must Go (2) - 野良C++erの雑記帳 ã§è§¦ããããã«ã
ç¾ç¶ã®å®è£
ã§ã¯ãä½æ
ããã¤ã³ã¿ããã大ããªãªãã¸ã§ã¯ããµã¤ãºãè¦æ±ãã¦ãã¾ãããã§ããã
ããã«ã¤ãã¦ã¯æ¬æ°ã§ççºããæ¹ãããã¨æã£ã¦ãã¾ããã
ããããã¡ã¢ãªå¹ç以å¤ã¯é常ã«åªç§ãªã®ã§ãç¥ããªãã¦ããçç±ã«ã¯ãªããªãçã§ãã
æ¬å½ã«å¹çãå¿
è¦ãªã¨ã以å¤ã¯ãç©æ¥µçã«ä½¿ãã¨ããããããªãã§ããããã
std::unique_ptr ( auto_ptr, scoped_ptr ) ã®ä»£æ¿ã¨ãã¦ã® Boost.Optional
ãã¦ãæå¾ã«ã Boost.Optional ãæãããªã¼ãã ã«ä½¿ãä¾ãæãã¾ãããã
寿å½ç®¡çã§ããä»»æã¿ã¤ãã³ã°ã§ã®çæï¼ç ´æ£ã§ããæ©éã³ã¼ããè¦ã¦ã¿ã¾ãããã
// ... class resource : boost::noncopyable { /* ... */ }; int main() { boost::optional<resource> rs; // boost::optional ã¯ã³ãã¼ãè¡ããã¨ãªãã¹ã³ã¼ããè¶ è¶ãã if( /* ... */ ) { /* å¦çã¨ã */ if( /* ... */ ) { // ãªã½ã¼ã¹ãæ§ç¯ï¼ rs = boost::in_place( /* å¼æ° */ ); } } if( rs ) { // ãªã½ã¼ã¹ãæ§ç¯ããã¦ããã // ãªã«ãå¦çããã /* ... */ // ãªã½ã¼ã¹ãæ¤å¦ã§ç ´æ£ï¼ rs = boost::none; } // æ´ã«å¦çãç¶è¡ãã /* ... */ }
resource ã¯ãç¹ã«å
·ä½ä¾ãæãæµ®ãã°ãªãã£ãã®ã§ ããããååã§ããã
åçã¡ã¢ãªç¢ºä¿ã¨ã RAII ãªãããé§ä½¿ãããæ¯è¼çãéããä½ããã¨ãã¦ãã ããã*8
è¦ãã°åããéããã¹ã³ã¼ããªãã¦ã¾ãã§åå¨ããªããã®ããã«ãèªç±èªå¨ã«æ±ãã¦ãã®ãåããã¨æãã¾ãã
ç¡è«ã C++ ã®ã¹ã³ã¼ãã¯å¤§äºãªæ¦å¿µãªã®ã§ãç¡è¦ãããã¨åºæ¬çã«ã¯å°ãããã§ããã
å®éåé¡ã¨ãã¦ãç¡è¦ãããå ´åã ã£ã¦å°ãªããªãã®ã§ãã
ãã®ãããªå ´åã«ä¾¿å©ããã ãªãã£ã¦ã®ããã³ã¼ããè¦ã¦ãªãã¨ãªãå¯ããã§ããããï¼
ã¾ããããã«ã¯ããä¸ã¤ã大äºãªãã¨ããã£ã¦ã
æåãã Boost.Optional ã使ããã¨ã決ãã¦ãã¾ãã°ã
resource ã¯ã©ã¹ã«ãç¡å¹ç¶æ
ããç¨æããå¿
è¦ããªããªãã¾ãã
é常ãã¯ã©ã¹ã«å¯¾ãã¦ç¹æ®ãªç¶æ
ã追å ãããã¨ã¯ããã°ã®æ¸©åºã¨ãªããã¾ãã
ä¸è¬ã«ã T åã®ãªãã¸ã§ã¯ãã¨ããã®ã¯ãããå¹çã失ããã«ç¡å¹ç¶æ
ã表ç¾ã§ããã¨ãã¦ãã
ã常ã«æå¹ãªç¶æ
ã«ãããã¨ããå¶ç´ã課ããæ¹ããè¨è¨ã®ã³ã¹ãããããã°ã®ã³ã¹ããå°ããã®ã§ãã
è¨ãæããã¨ãå
¨ã¦ã®ãªãã¸ã§ã¯ãã¯ãã³ã³ã¹ãã©ã¯ã¿ã®å¼ã³åºãããã£ã¦æå¹ç¶æ
ã«ãªãã
ãã¹ãã©ã¯ã¿ãå¼ã°ããã¾ã§æå¹ãªç¶æ
ãç¶æããã¹ãã§ãããã¨è¨ãã¾ãã*9
ããã¦ãç¹å¥ãªçç±ï¼åæåãé
延ãããã¨ãï¼ããã£ã¦ãç¡å¹ç¶æ
ãæ±ãããå ´åã¯ã Boost.Optional ã«ä»»ããã
ãããç¾ããå½¹å²åæ
ãç¾ããè¨è¨ãã¨ãããã®ã§ãããããã¯æãã¾ãããï¼
ãã Boost.Optional ã使ããã«ããããã®ã寿å½ãæå¹ï¼ç¡å¹ã®ç®¡çãè¡ãããå ´åã
boost::scoped_ptr
ãã®å ´åã§ã¯åçã¡ã¢ãªç¢ºä¿ãè¡ãã®ã§ãå°ãã°ããç¡é§ãªå¦çãè¡ãªããã¨ã«ãªãã¾ãã
ç¡è«ãåçã¡ã¢ãªç¢ºä¿ã®ã³ã¹ããªãã¦ç¡è¦åºæ¥ãç¨åº¦ã«å¾®ã
ãããã®ã§ããã
ããã«ãã£ã¦å¾ãããå¹æã¯å¤§ããã®ã§ã scoped_ptr ã unique_ptr ã使ããªãæã¯ãªãã®ã§ããã
åç´ã«ãåæåãé
延ãããããç ´æ£ãæ©ãããããã¹ã³ã¼ããè¶
è¶ããããã¨ããç¨åº¦ã®ç¨éãªãã
Boost.Optional ã使ããã¨ã«ãããåç確ä¿ãè¡ããªãåã ãé«éã«åä½ãããããã®ã§ãã
ããã§å¤§äºãªã®ãã前に少し触れたã boost::in_place ã使ã£ããªãã¸ã§ã¯ãã®ç´æ¥æ§ç¯ã§ããã
ããã使ããã¨ã«ãã£ã¦ã boost::optional
ä¾ã T ããããããã³ãã¼ã§ããªãåãã§ãã£ã¦ãæ ¼ç´ãããã¨ãåºæ¥ãããã«ãªããã
ã³ãã¼ã§ããåã«å¯¾ãã¦ããç´æ¥æ§ç¯ãããã¨ã§ãæ§ç¯ãã¦ããã³ãã¼ãããããå¦çéãæãããã¾ãã*10
ããã§ãã Boost.Optional ã¯ãå®ã®ã¨ããããåã«ç¡å¹ç¶æ
ã追å ãããã ãã®ä»£ç©ã§ã¯ãªãã®ã§ãã
Boost.Optional ã¯ãå®è¡å¹çãæ®ã©ä¸ããã«ãç¡å¹ç¶æ
ãæã¡è¾¼ãã¯ã©ã¹ãã§ãã
ã¤ã¾ããä¸è¬ã®ã¯ã©ã¹ãè¨è¨ããéã«ãæå¹ï¼ç¡å¹ã¯ Boost.Optional ã«ä»»ãã¦ã
ã¯ã©ã¹èªèº«ã¯è¦æ±ãããæ©è½ã®å®è£
ã®ã¿ã«å°å¿µãããã¨ããè¨è¨ãã¿ã¼ã³ãå¯è½ã«ãã¾ãã
ç¡è«ã Boost.Optional ã使ããªãã¦ãããã®ãããã¯åçã¡ã¢ãªç¢ºä¿ã«ãã£ã¦å®ç¾åºæ¥ããã¨ã§ããã
Boost.Optional ã®ã¡ãªããã¯ãã¨ã«ããå®è¡å¹çãæ®ã©ä¸ããªãã¨ããç¹ã§ããã
é度ããæ£ç¾©ã§ãã C++ ã§ã¯æ¥µãã¦æç¨ãªãã®ã§ãããã¨è¨ããã®ã§ãã
ãããæ¯ãã¦ããã®ãã boost::optional
ãã®æ¡ä»¶ã¨ã¯ã
- boost::optional
ãåã«æ§ç¯ãããåæç¸ãããããã ããªãã T ãã¹ã¿ãã¯ä¸ã«ç½®ããåã§ããããã¹ãã©ã¯ã¿ãä¾å¤ãæããªããã°è¯ãã - boost::optional
ãæ»ãå¤ã¨ãã¦ä½¿ãããå ´åï¼ã³ãã¼ãããå ´åï¼ã¯ãããã«å ã㦠T ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ãæã¡ããããã°è¯ãã
ãã£ãããã ãã§ãã
ãããã®æ¡ä»¶ããæºããã°ãã©ã®ãããªã¯ã©ã¹ã§ãã£ã¦ãã Boost.Optional ã®æ©æµã享åã§ãã¾ãã
ã¾ããããã©ã¼ãã³ã¹ä¸ã®è¦è«ãããæå¹ï¼ç¡å¹ãã¯ã©ã¹èªèº«ã«æããããç¶æ³ã§ãã£ã¦ãã
ãã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã Boost.Optional ã«æãã¦ããã°ãããããã¨ä¾¿å©ã«ãªãçã§ãã
ex. å 責äºé
æå¾ã«ãä¸å¿ããç´æã¨ãããã
Boost.Optional ã¯å¼·åã§ãããå¼·åãªãã®ã»ã©ã使ãéã誤ãã¨é
·ãç®ã«éãã¾ãã
ç¹ã«ãã¹ã³ã¼ãã®æ¦å¿µãã¨ãã¯ã C++ ã«ããã¦é常ã«å¤§äºãªæ¦å¿µã§ããã
Boost.Optional ãç¨ãã¦ã¹ã³ã¼ããè¶
ãããå ´åã¯ãæããã¦ãããæãè¯ãé¸æè¢ãªã®ãã
ãã£ã¨èªç¶ãªæ¸ãæ¹ã¯ãªãã®ãã©ããã常ã«èããªããè¡ãå¿
è¦ãããã¾ãã
ä¸æãããã¨ãåç
§å
ã®ãªãã¸ã§ã¯ããä¸æã«ç ´æ£ããã¦ãåãã«ãããã°ã®åå ã«ãªã£ãããã¾ãã
ã¨ã«ããããã®ãããã®æ²åã¯ã C++ ã使ãå ´åã«ã¯æ¬å½ã«å¤ãã
å®å
¨æ§ãèæ
®ããã¨ã optional ã§ã¯ãªã shared_ptr çã使ãã¹ãå±é¢ã¯ãããªãå¤ãã®ã§ãã
ã¾ããããã¨ã¯å¥ã«ã Boost.Optional ã¯åç
§ã§ã¯ãªãå¤ã®è«çã§åãã¾ãã
ã¤ã¾ãã巨大ãªãªãã¸ã§ã¯ããæ±ãããã¨ãã¹ã¿ãã¯æ¶è²»éãã³ãã¼ã³ã¹ãã馬鹿ã«ãªããªããã¨ãããã¨ã§ãã
ãããã常ã«èããä¸ã§ãåçã¡ã¢ãªç¢ºä¿ã¨ optional ãã©ã¡ããè¯ããã常ã«èããããã«ãã¾ãããã
C++ ã使ã以ä¸ãæèåæ¢ã¯å¯è½ãªéãé¿ããããã«ãããã§ããã
.
*1: å¿ä½ç¡ãã
*2: æ¬ä¼¼çãªãã¿ã¼ã³ãããã³ã°ã¨ãã¦ä½¿ãã¾ãããã¹ã³ã¼ãã if æä¸ã®ã¿ã«éå®ãããã®ã§å®å¿ã§ãã
*3: Boost.Range ã«å¯¾ãã BOOST_FOREACH ã¨ãã代表ä¾ã§ãããã便å©ã§ãã
*4: å¿è«ã *x = ãã ã¨ãã¦æ示çã«å¼ã¶ãã¨ã¯ããã¤ã§ãå¯è½ã§ãã
*5: å®éåé¡ã¨ãã¦ãã³ã³ã¹ãã©ã¯ã¿ã使ãããä»£å ¥æ¼ç®åã使ã£ã¦åä»£å ¥ãè¨è¨ããã°ãããã§ããåé¡ã§ãããããã§ãå®éã«ããããã¯ã©ã¹ã¯æå¹ã§ããããã¾ã§ãä¸è¬çã«ãä»£å ¥æ¼ç®åãç¡ãå ´åã§ããå®ç¾ãããã¨æã£ãããã¨ãããã¨ã§ãã
*6: ãã£ã¨ã boost::shared_ptr
*7: boost ã«ãããã¾ãããC++0xã§ãã§ããæ¨æºå ¥ããã¾ããããªã®ã§åå空éã¯æ¸ãã¦ã¾ããã
*8: ã¹ã¬ãã辺ãã¨ããæ³å®ãã¦ãããã°çµæ§ã§ãã
*9: ãã£ã¨è¨ãã¨ããã°ãæ¸ããããã«ã¯ã極åãã¹ãã©ã¯ã¿ã¯ã³ã³ãã¤ã©ã«ãã£ã¦èªåçæãããã¹ãã§ãã
*10: å®éã«ã¯æ»ãå¤æé©åã«ãã£ã¦å¦çéã¯å¤ãããªãå ´åãæ®ã©ã§ããããã