たとえば、次のように実装するにはどうすればよいですか
template <typename ITERATOR> void Swap (ITERATOR a, ITERATOR b) {
...
}
そのため、Swap(a, b) は a と b が指す値を交換します。つまり、データ型を知らずに 3 番目の変数を作成するにはどうすればよいでしょうか。
iter_swap
その仕事だけがあります:
std::iter_swap(a, b);
また、c++11 を使用できる場合は、以下を使用できますdecltype
。
std::remove_reference<decltype(*a)>::type c = *a;
*a = *b;
*b = c;
データ型を知らずに 3 番目の変数を作成するにはどうすればよいですか?
使用するstd::iterator_traits<ITERATOR>::value_type
C++11 では型は ですstd::remove_reference<decltype(*a)>::type
が、変数を宣言するには を使用しますauto
。
C++03 では、任意の式の型を推測する最も信頼できる方法は、別のテンプレートを使用することです。
// NOTE: This is for illustration only. If you are simply swapping
// values, use 'std::swap' instead of this, since that is specialised
// for many types to avoid unnecessary copy-assignment.
template <typename T> void value_swap(T & a, T & b) {
T t = a;
a = b;
b = t;
}
template <typename I> void iterator_swap(I a, I b) {
value_swap(*a, *b);
}
または、正常に動作する反復子 (ポインターと標準反復子を含む) の場合、型は として使用できますstd::iterator_traits<ITERATOR>::value_type
。iterator_traits
これは、デフォルトで必要なネストされた型を提供したり、それを特殊化したりせずに、誰かが独自のイテレータ型を作成した場合には機能しませんiterator_traits
。
一部のコンパイラは、次のような非標準の拡張機能を提供しdecltype
ます。たとえば、GCC は を提供しますtypeof
。コードを移植可能にする必要がない場合は、そのようなものを使用できます。
ところで、あなたの特定の関数はすでに として存在していstd::iter_swap
ます。
template <typename ITERATOR> void Swap (ITERATOR a, ITERATOR b) {
using std::swap;
swap(*a,*b);
}
イテレータには、その値の型を定義する、いわゆる特性があります。
iterator_traits<ITERATOR>::value_type temp = *a;
*a = *b;
*b = temp;