コンテナに要素を追加する場合、 vector::push_back, set::insert, stack::push を
同じように使いたいということがあって、そういう場合 C++03 では以下のようにします
#include <vector> #include <set> #include <stack> using namespace std; template <class Container, class T> inline void add(Container& c, const T& value) { c.push_back(value); } template <class T, class U> inline void add(set<T>& c, const U& value) { c.insert(value); } template <class T, class U> inline void add(stack<T>& c, const U& value) { c.push(value); } int main() { vector<int> v; set<int> st; stack<int> sk; add(v, 3); // v.push_back(3); add(st, 1); // st.insert(1); add(sk, 4); // sk.push(4); return 0; }
concept_map 使うと以下のように書けます
#include <vector> #include <set> #include <stack> concept AddAdapter<class X> { typename value_type; void add(X&, const value_type&); } template <class T> concept_map AddAdapter<std::vector<T>> { typedef typename std::vector<T>::value_type value_type; void add(std::vector<T>& v, const value_type& val) { v.push_back(val); } } template <class T> concept_map AddAdapter<std::set<T>> { typedef typename std::set<T>::value_type value_type; void add(std::set<T>& s, const value_type& val) { s.insert(val); } } template <class T> concept_map AddAdapter<std::stack<T>> { typedef typename std::stack<T>::value_type value_type; void add(std::stack<T>& s, const value_type& val) { s.push(val); } } template <AddAdapter adapter> void add(adaptoe& adter, const adaptor::value_type& val) { add(adter, val); } int main() { std::vector<int> v; std::set<int> st; std::stack<int> sk; add(v, 3); // v.push_back(3); add(st, 1); // st.insert(1); add(sk, 4); // sk.push(4); }
う〜ん、なんかめんどくさいな
#include <vector> #include <set> #include <stack> auto concept HasPushBack<class X> { typename value_type = X::value_type; void X::push_back(const value_type&); } auto concept HasInsert<class X> { typename value_type = X::value_type; void X::insert(const value_type&); } auto concept HasPush<class X> { typename value_type = X::value_type; void X::push(const value_type&); } template <HasPushBack Cont> void add(Cont& c, const Cont::value_type& val) { c.push_back(val); } template <HasInsert Cont> void add(Cont& c, const Cont::value_type& val) { c.insert(val); } template <HasPush Cont> void add(Cont& c, const Cont::value_type& val) { c.push(val); } int main() { std::vector<int> v; std::set<int> st; std::stack<int> sk; add(v, 3); // v.push_back(3); add(st, 1); // st.insert(1); add(sk, 4); // sk.push(4); }
Concept-based オーバーロードのほうがラクかも