c++boost.gif (8819 bytes)

Generic Programming Techniques

¤³¤ì¤Ï boost ¥é¥¤¥Ö¥é¥ê¤Ç»È¤ï¤ì¤Æ¤¤¤ë¡¢ ¥¸¥§¥Í¥ê¥Ã¥¯¥×¥í¥°¥é¥ß¥ó¥°µ»½Ñ¤ÎÉÔ´°Á´¤Ê³µ´Ñ¤Ç¤¢¤ë¡£

Table of Contents

Introduction

¥¸¥§¥Í¥ê¥Ã¥¯¥×¥í¥°¥é¥ß¥ó¥°¤Ï¥½¥Õ¥È¥¦¥§¥¢¥³¥ó¥Ý¡¼¥Í¥ó¥È¤ËÈÆÍѲ½¤Ë´Ø¤¹¤ë¤â¤Î¤Ç¤¢¤ê¡¢ ¤³¤ì¤Ë¤è¤ê¥³¥ó¥Ý¡¼¥Í¥ó¥È¤ò¿Íͤʾõ¶·¤ÇÍÆ°×¤ËºÆÍøÍѤ¹¤ë¤³¤È¤¬½ÐÍè¤ë¡£ C++ ¤Ç¤Ï¥¯¥é¥¹¥Æ¥ó¥×¥ì¡¼¥È¤È´Ø¿ô¥Æ¥ó¥×¥ì¡¼¥È¤¬¥¸¥§¥Í¥ê¥Ã¥¯¥×¥í¥°¥é¥ß¥ó¥°µ»½Ñ¤ËÂФ·¤ÆÆÃ¤Ë¸ú²ÌŪ¤Ç¤¢¤ë¡£ ¤Ê¤¼¤Ê¤é¡¢¤³¤ì¤é¤Ï¸úΨ¤òµ¾À·¤Ë¤¹¤ë¤³¤È¤Ê¤¯ÈÆÍѲ½¤ò²Äǽ¤Ë¤¹¤ë¤«¤é¤Ç¤¢¤ë¡£

¥¸¥§¥Í¥ê¥Ã¥¯¥×¥í¥°¥é¥ß¥ó¥°¤Î´Êñ¤ÊÎã¤È¤·¤Æ¡¢C ɸ½à¥é¥¤¥Ö¥é¥ê¤Î memcpy() ´Ø¿ô¤ò¤É¤Î¤è¤¦¤ËÈÆÍѲ½¤¹¤ë¤«¸«¤Æ¤ß¤è¤¦¡£ memcpy() ¤Î¼ÂÁõ¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£

void* memcpy(void* region1, const void* region2, size_t n)
{
  const char* first = (const char*)region2;
  const char* last = ((const char*)region2) + n;
  char* result = (char*)region1;
  while (first != last)
    *result++ = *first++;
  return result;
}
memcpy() ´Ø¿ô¤Ï´û¤Ë¡¢ void* ¤ò»È¤¦¤³¤È¤Ç¤¢¤ëÄøÅÙÈÆÍѲ½¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢ ¤³¤Î´Ø¿ô¤Ï°Û¤Ê¤ë¼ïÎà¤Î¥Ç¡¼¥¿ÇÛÎó¤Î¥³¥Ô¡¼¤Ë»È¤¦¤³¤È¤¬½ÐÍè¤ë¡£ ¤·¤«¤·¡¢¥³¥Ô¡¼¤·¤¿¤¤¥Ç¡¼¥¿¤¬ÇÛÎó¤ÎÃæ¤Ë¤Ê¤«¤Ã¤¿¤é¤É¤¦¤À¤í¤¦¡£ ¤³¤ì¤Ï¡¢¥ê¥ó¥¯¥ê¥¹¥È¤«¤â¤·¤ì¤Ê¤¤¡£¥³¥Ô¡¼¤Î³µÇ°¤ò¡¢ ¤É¤ó¤ÊÍ×ÁǤΥ·¡¼¥±¥ó¥¹¤Ë¤Ç¤âÈÆÍѲ½¤Ç¤­¤ë¤À¤í¤¦¤«¡£ memcpy() ¤ÎÃæ¿È¤ò¸«¤ë¤È¡¢¤³¤Î´Ø¿ô¤Î ºÇ¾®¸Â¤ÎÍ×µá ¤Ï¡¢¤¢¤ë¼ï¤Î¥Ý¥¤¥ó¥¿¤ò»È¤¦¤³¤È¤Ç¡¢¥·¡¼¥±¥ó¥¹¤ò ²£ÃÇ ¤·¡¢ »Ø¤µ¤ì¤¿Í×ÁÇ¤Ë ¥¢¥¯¥»¥¹ ¤·¡¢Í×ÁǤòÌÜŪÃÏ¤Ë ½ñ¤­¹þ¤ß ¡¢ ¤¤¤ÄÄä»ß¤¹¤ë¤«¤òÃΤ뤿¤á¤Ë¥Ý¥¤¥ó¥¿¤ò Èæ³Ó¤¹¤ë ɬÍפ¬¤¢¤ë¡£ C++ ɸ½à¥é¥¤¥Ö¥é¥ê¤Ï¤³¤Î¤è¤¦¤ÊÍ×µá¤ò ¥³¥ó¥»¥×¥È ¤ÎÃæ¤Ë¥°¥ë¡¼¥×²½¤¹¤ë¡£ ¤³¤Î¾ì¹ç¤Ï¡¢ Input Iterator ¥³¥ó¥»¥×¥È(region2) ¤È Output Iterator ¥³¥ó¥»¥×¥È (region1) ¤Ç¤¢¤ë¡£

¤â¤· memcpy() ¤ò´Ø¿ô¥Æ¥ó¥×¥ì¡¼¥È¤È¤·¤Æ½ñ¤­Ä¾¤·¡¢¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤ÎÍ×µá¤ò½Ò¤Ù¤ë¤¿¤á¤Ë¡¢ Input Iterator ¤È Output Iterator ¤òÍøÍѤ¹¤ë¤Ê¤é¡¢¼¡¤Î¤è¤¦¤Ë¤·¤Æ¡¢¹âÅ٤˺ÆÍøÍѲÄǽ¤Ê copy() ´Ø¿ô¤ò¼ÂÁõ¤¹¤ë¤³¤È¤¬½ÐÍè¤ë¡£

template <typename InputIterator, typename OutputIterator>
OutputIterator
copy(InputIterator first, InputIterator last, OutputIterator result)
{
  while (first != last)
    *result++ = *first++;
  return result;
}
ÈÆÍѤΠcopy() ´Ø¿ô¤ò»È¤¦¤³¤È¤Ç¡¢¤É¤ó¤Ê¼ïÎà¤Î¥·¡¼¥±¥ó¥¹¤«¤é¤Ç¤âÍ×ÁǤò¥³¥Ô¡¼¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ë¤Î¤Ç¤¢¤ë¡£ ¤³¤ì¤Ë¤Ï¡¢std::list ¤Î¤è¤¦¤Ê¡¢¥¤¥Æ¥ì¡¼¥¿¤ò³°Éô¤ËÃÖ¤¤¤Æ¤¤¤ë¥ê¥ó¥¯¥ê¥¹¥È¤â´Þ¤Þ¤ì¤ë¡£

#include <list>
#include <vector>
#include <iostream>

int main()
{
  const int N = 3;
  std::vector<int> region1(N);
  std::list<int> region2;

  region2.push_back(1);
  region2.push_back(0);
  region2.push_back(3);
  
  std::copy(region2.begin(), region2.end(), region1.begin());

  for (int i = 0; i < N; ++i)
    std::cout << region1[i] << " ";
  std::cout << std::endl;
}

Anatomy of a Concept

¥³¥ó¥»¥×¥È ¤ÏÍ×µá¤Î½¸¹ç¤Ç¤¢¤ê¡¢Í×µá¤ÏÍ­¸ú¤Ê¼°¡¢´ØÏ¢·¿¡¢ÉÔÊÑÎÌ¡¢ ¤½¤·¤Æ·×»»Î̤ÎÊݾڤ«¤é½ÐÍè¤Æ¤¤¤ë¡£Í×µá¤Î½¸¹ç¤òËþ¤¿¤¹·¿¤Ï¡¢¥³¥ó¥»¥×¥È¤Î ¥â¥Ç¥ë ¤È¸À¤ï¤ì¤ë¡£ ¥³¥ó¥»¥×¥È¤Ï¾¤Î¥³¥ó¥»¥×¥È¤ÎÍ×µá¤ò³ÈÄ¥¤¹¤ë¤³¤È¤¬²Äǽ¤Ç¤¢¤ê¡¢¤³¤ì¤Ï ȯŸ·¿ ¤È¸Æ¤Ð¤ì¤ë¡£

C++ ɸ½à¥é¥¤¥Ö¥é¥ê¤Ç»È¤ï¤ì¤Æ¤¤¤ë¥³¥ó¥»¥×¥È¤Ï SGI STL site ¤Çʸ½ñ²½¤µ¤ì¤Æ¤¤¤ë¡£

Traits

ÆÃÀ­¥¯¥é¥¹¤Ï¡¢¾ðÊ󤫤顢¥³¥ó¥Ñ¥¤¥ë»þ¤Î¹½À®Í×ÁÇ (·¿¡¢ÈÆÀ°¿ôÄê¿ô¡¢¥¢¥É¥ì¥¹) ¤òÏ¢ÁÛ¤¹¤ëÊýË¡¤òÄ󶡤¹¤ë¡£ Î㤨¤Ð¡¢¥¯¥é¥¹¥Æ¥ó¥×¥ì¡¼¥Èstd::iterator_traits<T> ¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë:

template <class Iterator>
struct iterator_traits {
  typedef ... iterator_category;
  typedef ... value_type;
  typedef ... difference_type;
  typedef ... pointer;
  typedef ... reference;
};
¤³¤ÎÆÃÀ­¥¯¥é¥¹¤Î value_type ¤Ï¡¢¥¤¥Æ¥ì¡¼¥¿¤¬ "»Ø¤·¼¨¤¹Àè¤Î" ·¿¤ËÂФ·¤Æ¡¢ ÈÆÍÑŪ¤Ê¥³¡¼¥É¤òÍ¿¤¨¤ë¡£ iterator_category ¤Ï¥¤¥Æ¥ì¡¼¥¿¤ÎǽÎϤ˰͸¤·¤Æ¡¢ ¤è¤ê¸úΨŪ¤Ê¥¢¥ë¥´¥ê¥º¥à¤òÁªÂò¤¹¤ë¤¿¤á¤ËÍøÍѤ¹¤ë¤³¤È¤¬½ÐÍè¤ë¡£

ÆÃÀ­¥Æ¥ó¥×¥ì¡¼¥È¤Î³Ë¤È¤Ê¤ëÆÃħ¤Ï¡¢¤³¤ì¤é¤¬ ¤Ç¤·¤ã¤Ð¤ê¤Ç¤Ï¤Ê¤¤ ¤È¤¤¤¦¤³¤È¤Ç¤¢¤ë: ¤³¤ì¤é¤Ï¾ðÊ󤫤顢ÁȤ߹þ¤ß¤Î·¿¡¢¥µ¡¼¥É¥Ñ¡¼¥Æ¥£¤Î¥é¥¤¥Ö¥é¥ê¤ÇÄêµÁ¤µ¤ì¤¿·¿¤ò´Þ¤á¡¢ Ǥ°Õ¤Î·¿¤Î¤òÏ¢ÁÛ¤¹¤ë¤³¤È¤ò²Äǽ¤Ë¤¹¤ë¡£Ä̾ÆÃÀ­¤ÏÆÃÀ­¥Æ¥ó¥×¥ì¡¼¥È¤ò(ÉôʬŪ¤Ë)ÌÀ¼¨¤¹¤ë¤³¤È¤Ç¡¢ ÆÃÄê¤Î·¿¤ËÆÃ²½¤µ¤ì¤Æ¤¤¤ë¡£

std::iterator_traits ¤Ë¤Ä¤¤¤Æ¤Î¾ÜºÙ¤Êµ­½Ò¤Ï¡¢ SGI ¤¬Ä󶡤·¤Æ¤¤¤ë ¤³¤Î¥Ú¡¼¥¸ ¤ò¸«¤è¡£ ɸ½à¥é¥¤¥Ö¥é¥ê¤Ç¤Î¡¢Â礭¤¯°Û¤Ê¤ëÊÌ¤ÎÆÃÀ­¤Î¼°¤Ï std::numeric_limits<T> ¤Ç¤¢¤ë¡£¤³¤ì¤Ï¡¢ ¿ôÃÍ·¿¤ÎÈϰϤÈǽÎϤòµ­½Ò¤¹¤ëÄê¿ô¤òÄ󶡤·¤Æ¤¤¤ë¡£

Tag Dispatching

ÆÃÀ­¥¯¥é¥¹¤ÈƱ»þ¤Ë»È¤ï¤ì¤ë¤³¤È¤¬Â¿¤¤µ»½Ñ¤Ë¡¢¥¿¥°Ê¬´ô¤¬¤¢¤ë¡£ ¤³¤ì¤Ï¡¢·¿¤ÎÀ­¼Á¤Ë´ð¤Å¤¤¤ÆÊ¬´ô¤¹¤ë¤¿¤á¤Ë¡¢´Ø¿ô¥ª¡¼¥Ð¡¼¥í¡¼¥É¤ò»È¤¦ÊýË¡¤Ç¤¢¤ë¡£ ¤³¤ì¤Ë¤Ä¤¤¤Æ¤Î¤è¤¤Îã¤Ï¡¢C++ ɸ½à¥é¥¤¥Ö¥é¥ê¤Î std::advance() ´Ø¿ô¤Ç¤¢¤ë¡£ ¤³¤ì¤Ï¡¢¥¤¥Æ¥ì¡¼¥¿¤ò n ²ó¥¤¥ó¥¯¥ê¥á¥ó¥È¤¹¤ë¡£ ¥¤¥Æ¥ì¡¼¥¿¤Î¼ïÎà¤Ë¤è¤Ã¤Æ¡¢¼ÂÁõ¤ÎÃæ¤Ç¤ÏŬÍѤµ¤ì¤ë¡¢°Û¤Ê¤ëºÇŬ²½¤¬¤¢¤ë¡£ ¤â¤·¥¤¥Æ¥ì¡¼¥¿¤¬ random access (Á°Êý¡¢¸åÊý¤ËǤ°Õ¤Îµ÷Î¥¡¢¥¸¥ã¥ó¥×¤¹¤ë¤³¤È¤¬²Äǽ¤Ç¤¢¤ë) ¤Ê¤é¡¢ advance() ´Ø¿ô¤Ïñ¤Ë i += n ¤Ç¼ÂÁõ¤µ¤ì¡¢¤³¤ì¤ÏÈó¾ï¤Ë¸úΨŪ¡¢¤Ä¤Þ¤êÄê¿ô»þ´Ö¤Ç¤¢¤ë¡£ ¾¤Î¥¤¥Æ¥ì¡¼¥¿¤Ç¤Ï¡¢ ¥¹¥Æ¥Ã¥×¿ô¤¬ ¾å¾º ¤·¡¢±é»»¤Ï n ¤ËÂФ¹¤ëÀþ·Á»þ´Ö¤Ë¤Ê¤ë¡£ ¤â¤·¥¤¥Æ¥ì¡¼¥¿¤¬¡¢ ÁÐÊý¸þ ¤Ê¤é¡¢ n ¤¬Éé¤Ç¤¢¤Ã¤Æ¤âÎɤ¤¤Î¤Ç¡¢ ¥¤¥Æ¥ì¡¼¥¿¤ò¥¤¥ó¥¯¥ê¥á¥ó¥È¤¹¤ë¤«¥Ç¥¯¥ê¥á¥ó¥È¤¹¤ë¤«Áª¤Ð¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£

¥¿¥°Ê¬´ô¤ÈÆÃÀ­¥¯¥é¥¹¤Î´Ø·¸¤Ï¡¢Ê¬´ô¤Ë»È¤ï¤ì¤ëÀ­¼Á(¤³¤Î¾ì¹ç¤Ç¤Ï iterator_category) ¤¬ÆÃÀ­¥¯¥é¥¹¤Ë¤è¤Ã¤Æ¥¢¥¯¥»¥¹¤µ¤ì¤ë¤³¤È¤¬Â¿¤¤¡¢¤È¤¤¤¦¤³¤È¤Ç¤¢¤ë¡£ ¼ç¤¿¤ë advance() ´Ø¿ô¤Ï iterator_category ¤òÆÀ¤ë¤¿¤á¤Ë iterator_traits ¥¯¥é¥¹¤ò»È¤¦¡£ ¤½¤ì¤«¤é¡¢¥ª¡¼¥Ð¡¼¥í¡¼¥É¤µ¤ì¤¿ advance_dispatch() ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¤Î¤Ç¤¢¤ë¡£ iterator_category ¤ò¤É¤ó¤Ê·¿¤Ë²ò·è¤¹¤ë¤«¤Ë´ð¤Å¤¤¤Æ¡¢ ¥³¥ó¥Ñ¥¤¥é¤Ë¤è¤ê¡¢ input_iterator_tag ¤« bidirectional_iterator_tag ¤« random_access_iterator_tag ¤ÎÃæ¤«¤éŬ¤·¤¿ advance_dispatch() ¤¬Áª¤Ð¤ì¤ë¤Î¤Ç¤¢¤ë¡£ ¥¿¥° ¤Ï¥¿¥°Ê¬´ô¤ä¡¢»÷¤¿¤è¤¦¤Êµ»½Ñ¤Ç»È¤¦¤¿¤á¤ÎÀ­¼Á¤òÅÁ¤¨¤ë¡¢ ¤È¤¤¤¦ÌÜŪ¤À¤±¤ò»ý¤Äñ½ã¤Ê¥¯¥é¥¹¤Ç¤¢¤ë¡£ ¥¤¥Æ¥ì¡¼¥¿¥¿¥°¤Î¤è¤ê¾ÜºÙ¤Êµ­½Ò¤Ë¤Ä¤¤¤Æ¤Ï¡¢¤³¤Î¥Ú¡¼¥¸ ¤ò»²¾È¤¹¤ë¤³¤È¡£

namespace std {
  struct input_iterator_tag { };
  struct bidirectional_iterator_tag { };
  struct random_access_iterator_tag { };

  namespace detail {
    template <class InputIterator, class Distance>
    void advance_dispatch(InputIterator& i, Distance n, input_iterator_tag) {
      while (n--) ++i;
    }

    template <class BidirectionalIterator, class Distance>
    void advance_dispatch(BidirectionalIterator& i, Distance n, 
       bidirectional_iterator_tag) {
      if (n >= 0)
        while (n--) ++i;
      else
        while (n++) --i;
    }

    template <class RandomAccessIterator, class Distance>
    void advance_dispatch(RandomAccessIterator& i, Distance n, 
       random_access_iterator_tag) {
      i += n;
    }
  }

  template <class InputIterator, class Distance>
  void advance(InputIterator& i, Distance n) {
    typename iterator_traits<InputIterator>::iterator_category category;
    detail::advance_dispatch(i, n, category);
  }
}

Adaptors

¥¢¥À¥×¥¿ ¤ÏÊ̤η¿¤ä¡¢¿·¤·¤¤¥¤¥ó¥¿¥Õ¥§¡¼¥¹¡¢¥Ó¥Ø¥¤¥Ó¥¢¤ÎÊѼï¤òÄ󶡤¹¤ë·¿¤ò¹½ÃÛ¤¹¤ë¡¢ ¥¯¥é¥¹¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤¢¤ë¡£ ɸ½à¤Î¥¢¥À¥×¥¿¤ÎÎã¤Ï¡¢ std::reverse_iterator ¤Ë¤¢¤ë¡£¤³¤ì¤Ï¡¢¥¤¥ó¥¯¥ê¥á¥ó¥È¡¢¥Ç¥¯¥ê¥á¥ó¥È¤ËÂФ·¤½¤Îư¤­¤ÎµÕž¤µ¤»¤ë¡¢¥¤¥Æ¥ì¡¼¥¿·¿¤ËÂФ¹¤ë¥¢¥À¥×¥¿¤Ç¤¢¤ë¡£ std::stack ¤Ïñ½ã¤Ê¥¹¥¿¥Ã¥¯¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤òÄ󶡤¹¤ë¥³¥ó¥Æ¥Ê¤ËÂФ¹¤ë¥¢¥À¥×¥¿¤Ç¤¢¤ë¡£

ɸ½à¤Ç¤Î¥¢¥À¥×¥¿¤Ë¤Ä¤¤¤Æ¤Î¡¢¤è¤ê²ò¤ê¤ä¤¹¤¤¥ì¥Ó¥å¡¼¤Ï ¤³¤³ ¤Ë¤¢¤ë¡£

Type Generators

type generator ¤Ï¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô [1] ¤Ë´ð¤Å¤¤¤Æ¿·¤·¤¤·¿¤ò¹çÀ®¤¹¤ë¤³¤È¤À¤±¤¬ÌÜŪ¤Î¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤¢¤ë¡£ À¸À®¤µ¤ì¤¿·¿¤ÏÄ̾¥Í¥¹¥È¤µ¤ì¤¿ typedef ¤Ç̾Á°ÉÕ¤±¤µ¤ì¡¢¤¤¤«¤Ë¤â¤Õ¤µ¤ï¤·¤¯ type ¤È¤·¤ÆÉ½¸½¤µ¤ì¤ë¡£ ·¿À¸À®¤ÏÄ̾ʣ»¨¤Ê·¿É½¸½¤ò¤Ò¤È¤Ä¤Î·¿¤ËÀ©»ß¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¡£Î㤨¤Ð¡¢ boost::filter_iterator_generator ¤Ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë:

template <class Predicate, class Iterator, 
    class Value = complicated default,
    class Reference = complicated default,
    class Pointer = complicated default,
    class Category = complicated default,
    class Distance = complicated default
         >
struct filter_iterator_generator {
    typedef iterator_adaptor<
        Iterator,filter_iterator_policies<Predicate,Iterator>,
        Value,Reference,Pointer,Category,Distance> type;
};

¤¤¤Þ¤³¤ì¤ÏÊ£»¨¤À¤¬¡¢Å¬±þ¤¹¤ë¥Õ¥£¥ë¥¿¥¤¥Æ¥ì¡¼¥¿¤òºî¤ë¤Î¤Ï´Êñ¤Ç¤¢¤ë¡£ ¤¢¤Ê¤¿¤ÏÉáÄÌ¡¢¤¿¤À¤³¤¦½ñ¤¯¤À¤±¤Ç¤è¤¤:

boost::filter_iterator_generator<my_predicate,my_base_iterator>::type

Object Generators

object generator ¤Ï´Ø¿ô¥Æ¥ó¥×¥ì¡¼¥È¤Ç¤¢¤ê¡¢Í£°ì¤ÎÌÜŪ¤Ï¡¢ °ú¿ô¤«¤é¿·¤·¤¤¥ª¥Ö¥¸¥§¥¯¥È¤ò¹½ÃÛ¤¹¤ë¤³¤È¤Ç¤¢¤ë¡£ ÈÆÍÑ¥³¥ó¥¹¥È¥é¥¯¥¿¤Î°ì¼ï¤È¤·¤Æ¹Í¤¨¤ë¤³¤È¤¬½ÐÍè¤ë¤À¤í¤¦¡£ ¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®´ï¤Ï¡¢À¸À®¤µ¤ì¤ë¼ÂºÝ¤Î·¿¤òɽ¸½¤¹¤ë¤Î¤¬Æñ¤·¤«¤Ã¤¿¤ê¡¢½ÐÍè¤Ê¤«¤Ã¤¿¤ê¤¹¤ë¤È¤­¤Ë¡¢ ñ¤Ê¤ë¥³¥ó¥¹¥È¥é¥¯¥¿¤è¤ê¤âÌòΩ¤Ä¤À¤í¤¦¡£ ¤½¤·¤ÆÀ¸À®´ï¤Î·ë²Ì¤ÏÊÑ¿ô¤Ë³ÊǼ¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢Ä¾ÀÜ´Ø¿ô¤ËÅϤ¹¤³¤È¤â½ÐÍè¤ë¡£ ¿¤¯¤Î Boost ¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®´ï¤ÏÀÜÆ¬¼­ "make_" ¤¬¤Ä¤±¤é¤ì¤Æ¤¤¤ë¡£ ¤³¤ì¤Ï¡¢std::make_pair(constŽ T&,Ž constŽ U&) ¤ËÊï¤Ã¤Æ¤Î¤³¤È¤Ç¤¢¤ë¡£

¤¿¤È¤¨¤Ð¡¢¼¡¤Î¤è¤¦¤Ê¤â¤Î¤ò¹Í¤¨¤Æ¤ß¤ë:

struct widget {
  void tweak(int);
};
std::vector<widget *> widget_ptrs;
2¤Ä¤Îɸ½à¤Î¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®´ï¡¢ std::bind2nd() ¤È std::mem_fun() ¤òÏ¢º¿¤¹¤ë¤³¤È¤Ç¡¢Á´¤Æ¤ÎÁõÃÖ¤ò´Êñ¤Ë¤Ä¤Þ¤à¤³¤È¤¬½ÐÍè¤ë:
void tweak_all_widgets1(int arg)
{
   for_each(widget_ptrs.begin(), widget_ptrs.end(),
      bind2nd(std::mem_fun(&widget::tweak), arg));
}

¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®´ï¤ò»È¤ï¤Ê¤±¤ì¤Ð¡¢¾å¤ÎÎã¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ë:

void tweak_all_widgets2(int arg)
{
   for_each(struct_ptrs.begin(), struct_ptrs.end(),
      std::binder2nd<std::mem_fun1_t<void, widget, int> >(
          std::mem_fun1_t<void, widget, int>(&widget::tweak), arg));
}

ɽ¸½¤¬¤è¤êÊ£»¨¤Ë¤Ê¤ë¤Ë¤Ä¤ì¤Æ¡¢·¿»ØÄê¤Î¾éĹÀ­¤ò¸º¤é¤¹É¬Í×À­¤Ï¤É¤¦¤·¤Æ¤âÂ礭¤¯¤Ê¤ë¤Î¤Ç¤¢¤ë¡£

Policy Classes

¥Ý¥ê¥·¡¼¥¯¥é¥¹¤Ï¥Ó¥Ø¥¤¥Ó¥¢¤òÅÁ㤹¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤Ç¤¢¤ë¡£ ɸ½à¥é¥¤¥Ö¥é¥ê¤«¤é¤ÎÎã¤Ï std::allocator ¤Ç¤¢¤ë¡£¤³¤ì¤Ï¡¢¥á¥â¥ê´ÉÍý¤Î¥Ó¥Ø¥¤¥Ó¥¢¤òɸ½à¤Î containers ¤ËÅÁ¤¨¤ë¡£

¥Ý¥ê¥·¡¼¥¯¥é¥¹¤Ï Andrei Alexandrescu ¤Ë¤è¤Ã¤Æ¡¢ ¤³¤Îʸ½ñ ¤ÎÃæ¤Ç¾Ü¤·¤¯Ãµµá¤µ¤ì¤Æ¤¤¤ë¡£Èà¤Ï¼¡¤Î¤è¤¦¤Ë½ñ¤¤¤Æ¤¤¤ë:

¥Ý¥ê¥·¡¼¥¯¥é¥¹¤ÏÑÜÄ¢Ì̤ʥǥ¶¥¤¥óÁªÂò¤Î¼ÂÁõ¤Ç¤¢¤ë¡£ ¤³¤ì¤é¤Ï¾¤Î¥¯¥é¥¹¤«¤éÇÉÀ¸¤·¤Æ¤¤¤ë¤«¡¢Â¾¤Î¥¯¥é¥¹¤Ë´Þ¤Þ¤ì¤Æ¤¤¤Æ¡¢ ¹½Ê¸Åª¤ËƱ¤¸¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Î²¼¤Ç¡¢°Û¤Ê¤ëÀïά¤òÄ󶡤¹¤ë¡£ ¥Ý¥ê¥·¡¼¤ò»È¤¦¥¯¥é¥¹¤Ï¡¢¤½¤ì¤¬»È¤¦¤½¤ì¤¾¤ì¤Î¥Ý¥ê¥·¡¼¤ËÂФ·¤Æ¤Ò¤È¤Ä¤Î¥Æ¥ó¥×¥ì¡¼¥È°ú¿ô¤ò»ý¤Ã¤Æ¡¢ ¥Æ¥ó¥×¥ì¡¼¥È²½¤µ¤ì¤Æ¤¤¤ë¡£ ¤³¤Î¤¿¤á¥æ¡¼¥¶¤ÏɬÍפʥݥꥷ¡¼¤òÁªÂò¤¹¤ë¤³¤È¤¬½ÐÍè¤ë¤Î¤Ç¤¢¤ë¡£

¥Ý¥ê¥·¡¼¥¯¥é¥¹¤ÎÎϤϡ¢¤½¤ÎǽÎϤò¼«Í³¤ËÁȤ߹ç¤ï¤»¤ë¤³¤È¤«¤éÍè¤ë¡£ ¥Æ¥ó¥×¥ì¡¼¥È¥¯¥é¥¹¤ÎÃæ¤Î¤¤¤¯¤Ä¤«¤Î¥Ý¥ê¥·¡¼¥¯¥é¥¹¤òÊ£¿ô¤Î°ú¿ô¤ÈÁȤ߹ç¤ï¤»¤ë¤³¤È¤Ç¡¢ ¥³¡¼¥É¤ÎÎ̤ò¤½¤ì¤Û¤ÉÁý¤ä¤¹¤³¤È¤Ê¤¯¡¢ÁȤ߹ç¤ï¤»¤¿¥Ó¥Ø¥¤¥Ó¥¢¤ò¼Â¸½¤¹¤ë¡£

Andrei ¤Î¥Ý¥ê¥·¡¼¥¯¥é¥¹¤Ë¤Ä¤¤¤Æ¤Îµ­½Ò¤Ï¡¢¤½¤ÎÎϤò¡¢ γ¾õÀ­¤Èľ¸òÀ­¤«¤é°ú¤­½Ð¤µ¤ì¤ë¤â¤Î¤È¤·¤Æ½Ò¤Ù¤Æ¤¤¤ë¡£ Boost ¤Ï¤ª¤½¤é¤¯¡¢Iterator Adaptors ¥é¥¤¥Ö¥é¥ê¤ÎÃæ¤Ç¤³¤ÎÆÃħ¤ò¼å¤á¤Æ¤¤¤ë¡£ ¤³¤Î¥é¥¤¥Ö¥é¥ê¤Ç¤Ï¡¢Å¬ÍѤµ¤ì¤¿¥¤¥Æ¥ì¡¼¥¿¤Î¥Ó¥Ø¥¤¥Ó¥¢Á´¤Æ¤ò¤Ò¤È¤Ä¤Î¥Ý¥ê¥·¡¼¥¯¥é¥¹¤ËÅÁ¤¨¤Æ¤¤¤ë¡£ ¤·¤«¤·¡¢¤³¤ì¤Ë¤ÏÁ°Î㤬¤¢¤ë: std::char_traits ¤Ï¤½¤Î̾Á°¤Ë¤â¤«¤«¤ï¤é¤º¡¢std::basic_string ¤Î¥Ó¥Ø¥¤¥Ó¥¢¤ò·èÄꤹ¤ë¥Ý¥ê¥·¡¼¥¯¥é¥¹¤È¤·¤ÆÆ¯¤¤¤Æ¤¤¤ë¤Î¤Ç¤¢¤ë¡£

Notes

[1] ·¿À¸À®´ï¤Ï¡¢ C++ ¤Ë ``¥Æ¥ó¥×¥ì¡¼¥È¤Î typedef'' ¤¬Â¸ºß¤·¤Ê¤¤¤³¤È¤ËÂФ¹¤ëÂåÂØ¼êÃʤǤ¢¤ë¡£

Revised 14 Mar 2001

© Copyright David Abrahams 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.


Japanese Translation Copyright (C) 2003 Kohske Takahashi

¥ª¥ê¥¸¥Ê¥ë¤Î¡¢µÚ¤Ó¤³¤ÎÃøºî¸¢É½¼¨¤¬Á´¤Æ¤ÎÊ£À½¤ÎÃæ¤Ë¸½¤ì¤ë¸Â¤ê¡¢¤³¤Îʸ½ñ¤Î Ê£À½¡¢ÍøÍÑ¡¢Êѹ¹¡¢ÈÎÇ䤽¤·¤ÆÇÛÉÛ¤òǧ¤á¤ë¡£¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ï¡Ö¤¢¤ë¤¬¤Þ¤Þ¡× ¤ËÄ󶡤µ¤ì¤Æ¤ª¤ê¡¢¤¤¤«¤Ê¤ëÌÀ¼¨Åª¡¢°ÅÌÛŪÊݾڤâ¹Ô¤ï¤Ê¤¤¡£¤Þ¤¿¡¢ ¤¤¤«¤Ê¤ëÌÜŪ¤ËÂФ·¤Æ¤â¡¢¤½¤ÎÍøÍѤ¬Å¬¤·¤Æ¤¤¤ë¤³¤È¤ò´ØÃΤ·¤Ê¤¤¡£