2012-04-11 84 views
3

我如何能实现例如以下std :: sort如何仅使用迭代器实现交换操作?

template <typename ITERATOR> void Swap (ITERATOR a, ITERATOR b) { 
    ... 
} 

使交换(A,B)交换值在由a和b指出。换句话说:如何在不知道数据类型的情况下创建第三个变量?

+0

你的意思是'std :: swap',而不是'std :: sort',对吧? – juanchopanza 2012-04-11 14:16:18

+0

好吧,这些只是例子。我想做一些重新安排/重新分配的容器,我只通过迭代器,我需要一些临时变量。 – Michael 2012-04-11 14:28:13

+0

@ juanchopanza:不,我不认为他是这个意思。如果用'std :: swap'替换'std :: sort',这个问题甚至没有意义,因为'std :: swap'不能用于迭代器。它只是交换迭代器本身,而不是它们指向的值,而这显然不是OP所要做的。 – 2012-04-11 14:30:18

回答

6

如何创建一个第三个变量不知道数据类型?

使用std::iterator_traits<ITERATOR>::value_type

+0

我不知道。谢谢。 – Michael 2012-04-11 14:37:16

2

迭代器有一个所谓的特征来定义它的值类型。

 iterator_traits<ITERATOR>::value_type temp = *a; 
     *a = *b; 
     *b = temp; 
7

iter_swap只是那份工作,

std::iter_swap(a, b); 

此外,如果你可以使用C++ 11可以使用decltype

std::remove_reference<decltype(*a)>::type c = *a; 
*a = *b; 
*b = c; 
+0

这很有帮助。 – Michael 2012-04-11 14:38:20

+0

@Dani:'swap(* a,* b)'? – 2012-04-11 15:20:04

3
template <typename ITERATOR> void Swap (ITERATOR a, ITERATOR b) { 
    using std::swap; 
    swap(*a,*b); 
} 
+0

相当,但不完全。 '使用std :: swap; swap(* a,* b);'因为用户类型不需要专门化'std :: swap',他们可能只是在自己的命名空间中提供'swap'函数,并依靠ADL来提取它。 – 2012-04-11 15:22:41

4

在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

+0

谢谢,这很有帮助 – Michael 2012-04-12 10:14:24