findé¢æ°ã§è¦ãC++ã®å¤å
STLã¢ã«ã´ãªãºã ã¯ãã®ã¢ã«ã´ãªãºã ãé©ç¨ããç¯å²ã®å é ã¨æ«å°¾ã®ã¤ãã¬ã¼ã¿ã®ãã¢ãå¼æ°ã«åãã¾ããå®éã«ã¯ç¯å²å ¨ä½ã«ã¢ã«ã´ãªãºã ãé©ç¨ãããã±ã¼ã¹ãå¤ããã¤ãã¬ã¼ã¿ã®ãã¢ãæ¸ãã®ãåé·ã«æãããã¨ãããã¾ããããã§Boost.Rangeã«ã¯ãç¯å²ãå¼æ°ã«æ¸¡ããã¨ã§ãã®ç¯å²å ¨ä½ã«STLã¢ã«ã´ãªãºã ãé©ç¨ããé¢æ°ãã¡ãããã¾ããBoost.Rangeã®findé¢æ°ã®å®è£ ä¾ãè¦ã¦C++03/C++11/C++14ã®æ¯è¼ããããã¨æãã¾ãã
C++03
ã¾ããç¯å²ãªãä½ã§ããã³ã³ããã§ãçµã¿è¾¼ã¿é åã§ãã¢ã«ã´ãªãºã ã«é©ç¨ã§ããããã«ãbeginé¢æ°ãendé¢æ°ãå®ç¾©ãã¾ãã
namespace ns { //ã³ã³ããçbegin/endé¢æ° //éconstãconstã§ãªã¼ãã¼ãã¼ã template <typename Container> typename Container::iterator begin(Container& c) { return c.begin(); } template <typename Container> typename Container::const_iterator begin(Container const& c) { return c.begin(); } template <typename Container> typename Container::iterator end(Container& c) { return c.end(); } template <typename Container> typename Container::const_iterator end(Container const& c) { return c.end(); } //çµã¿è¾¼ã¿é åçbegin/endé¢æ° template <typename T, std::size_t N> T* begin(T (&ar)[N]) { return ar; } template <typename T, std::size_t N> T* end(T (&ar)[N]) { return ar + N; }
ã³ã³ããã¨çµã¿è¾¼ã¿é
åã®ãªã¼ãã¼ãã¼ãã¯æ»ãå¤ã®åã®typename Container::iterator
ãããã§SFINAEãã¦ãã¾ãã
ããã«ãC++03ã§ã¯é¢æ°ã®æ»ãå¤ã®åæ¨è«ãããæ©è½ã¯ããã¾ããã®ã§findé¢æ°ã®æ»ãå¤ã®åãæ±ããããã®ã¡ã¿é¢æ°ãä½æãã¾ãã
//ã³ã³ããçrange_iterator //éconstãconstã§é¨åç¹æ®å template <typename Container> struct range_iterator { typedef typename Container::iterator type; }; template <typename Container> struct range_iterator<Container const> { typedef typename Container::const_iterator type; }; //çµã¿è¾¼ã¿é åçrange_iterator //éconstãconstã§é¨åç¹æ®å template <typename T, std::size_t N> struct range_iterator<T[N]> { typedef T* type; }; template <typename T, std::size_t N> struct range_iterator<T const[N]> { typedef T const* type; };
ããã§findé¢æ°ãå®ç¾©ããæºåãåºæ¥ã¾ããã
findé¢æ°ãå®è£
ãã¾ãã
template <typename Range, typename T> typename range_iterator<Range>::type find(Range& rng, T const& value) { return std::find(ns::begin(rng), ns::end(rng), value); } template <typename Range, typename T> typename range_iterator<Range>::type find(Range const& rng, T const& value) { return std::find(ns::begin(rng), ns::end(rng), value); } }
使ç¨ãã¾ãã
#include <vector> int main() { std::vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); ns::find(v, 2); int a[] = {10, 20, 30}; ns::find(a, 20); }
C++11
begin/endãæ¨æºå
¥ãããã®ã§ãèªåã§ä½æããå¿
è¦ããªããªãã¾ãããããã«ãæ»ãå¤ã®åãæ±ããã¡ã¿é¢æ°ããC++11ã§æ»ãå¤ã®å¾æ¹é
ç½®ã¨å¼ããåãæ±ããdecltypeãå
¥ãã¾ããã®ã§å¿
è¦ç¡ããªãã¾ãã
以ä¸ã®ã³ã¼ããC++11ã®findé¢æ°ã§ãã
namespace ns { template <typename Range, typename T> auto find(Range& rng, T const& value) -> decltype(std::find(std::begin(rng), std::end(rng), value)) { return std::find(std::begin(rng), std::end(rng), value); } template <typename Range, typename T> auto find(Range const& rng, T const& value) -> decltype(std::find(std::begin(rng), std::end(rng), value)) { return std::find(std::begin(rng), std::end(rng), value); } }
使ç¨ã³ã¼ãã§ãã
int main() { std::vector<int> v = {1, 2, 3}; ns::find(v, 2); int a[] = {10, 20, 30}; ns::find(a, 20); }
C++14
C++14ã§ã¯begin/endã ãã§ãªãcbegin/cendé¢æ°ãrbegin/rendé¢æ°ãcrbegin/crendé¢æ°ã追å ããã¾ãããããã¦ãé常é¢æ°ã®æ»ãå¤ã®åæ¨è«ã追å ããã¾ããããã£ã¦C++14ã«ãããfindé¢æ°ã®å®è£ ã¯ä»¥ä¸ã«ãªãã¾ãã
namespace ns { template <typename Range, typename T> auto find(Range& rng, T const& value) { return std::find(std::begin(rng), std::end(rng), value); } template <typename Range, typename T> auto find(Range const& rng, T const& value) { return std::find(std::cbegin(rng), std::cend(rng), value); } }
使ç¨ã³ã¼ãã¯C++11ã¨åæ§ãªã®ã§å²æãã¾ãã
C++11ã¨æ¯ã¹ã¦decltypeã«æ»ãå¤ã®å¼ããã1度æ¸ãåé·æ§ããªããªãã¾ããã
ã¾ã¨ã
C++ãé²åããã«ã¤ãã¦ãããç°¡åã«(ããããç¹æ®ãªãã¯ããã¯ãç¥ããã«)ããã¸ã§ããªãã¯ãªã³ã¼ããæ¸ããããã«ãªã£ã¦ãã¾ãããC++ã¯ããç°¡åã«ããæ±ç¨çã«ããå®å ¨ã«ããå¹ççã«ã³ã¼ããæ¸ããããã«é²åãã¦ããã¨ç§ã¯æãã¦ãã¾ãã