C++0xからConceptが導入されますが、現在のC++でも使えるConceptを作ってみました
とりあえずContainerコンセプトだけです
Containerコンセプトを使えば、コンテナと配列を同じように扱うことができます
namespace concept { template <class T> struct identity { typedef T type; }; template <class Container> struct container { typedef Container type; typedef typename Container::value_type value_type; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; typedef typename Container::iterator iterator; typedef typename Container::const_iterator const_iterator; typedef typename Container::difference_type difference_type; typedef typename Container::size_type size_type; static iterator begin(Container& c) { return c.begin(); } static const_iterator begin(const Container& c) { return c.begin(); } static iterator end(Container& c) { return c.end(); } static const_iterator end(const Container& c) { return c.end(); } static size_type size(const Container& c) { return c.size(); } }; template <class T, int N> struct container<T[N]> : identity<T[N]> { typedef T value_type; typedef T& reference; typedef const T& const_reference; typedef T* iterator; typedef const T* const_iterator; typedef T difference_type; typedef std::size_t size_type; static iterator begin(T (&ar)[N]) { return ar; } static const_iterator begin(const T (&ar)[N]) { return ar; } static iterator end(T (&ar)[N]) { return ar + N; } static const_iterator end(const T (&ar)[N]) { return ar + N; } static size_type size(const T (&ar)[N]) { return N; } }; } // namespace concept
使い方
template <class Container> void foo(Container& c) { typedef typename concept::container<Container> concept_type; typename concept_type::value_type value; sort(concept_type::begin(c), concept_type::end(c)); } int main() { vector<int> v; int ar[3]; foo(v); // OK foo(ar); // OK int value; foo(value); // エラー! return 0; }
こういうふうに使えればもっと良かった(?)のですが
template <class Container> void foo(typename concept::container<Container>::type& c) { }
これをやると関数テンプレートのテンプレート引数を指定しなければいけなくなります
自作コンテナを使用する場合は、containerコンセプトの要求(インターフェース)に合わせるか
containerコンセプトを特殊化してください(concept_mapみたいに)