我喜欢STL算法,更喜欢使用算法而不是通常的循环 几乎所有STL算法通常用作:
std::algorithm_name( container.begin(), container.end(), ..... )
container.begin(), container.end()
- 是我项目中最受欢迎的单词对之一。
有人有同样的问题吗? 你们是怎么解决这个问题的? 您有什么建议可以避免这种重复?我看到了一些解决方法,但它们都有不同的限制(宏使用,与通常的指针不兼容等)。
答案 0 :(得分:28)
下一个C ++标准,C ++ 0X(其中X代表,希望是9)将增加从迭代器角度转换到容器角度的可能性。你将能够做到例如。
的std ::排序(my_vec);
如果您不能等待,我建议您查看:Boost.Range
如果您对迭代器/范围非常感兴趣,我建议您阅读Andrei的“ iterators must go ”
答案 1 :(得分:19)
许多人遇到了这种麻烦。虽然迭代器概念非常普遍,但缺乏一些可用性。
输入'范围'概念。最好避免任何代码重复。因此,如果您在整个代码中遇到.begin()和.end(),那么最好在'iterator-getting'和实际算法之间创建一个层。
参考文献:
...
答案 2 :(得分:7)
#define ALL(x) (x).begin(), (x).end()
sort(ALL(vec));
答案 3 :(得分:3)
C++11已经解决了语言中的这种轻微烦恼。
答案 4 :(得分:3)
首先,我认为这不是一个大问题。一般来说,我真的不在乎输入更多的字符。可读性更重要,我认为开始/结束是完全可读的。
较短的容器名称可以提供帮助(con.begin()比container.begin()更容易输入)
传递迭代器而不是容器本身意味着在任何情况下都不必多次调用begin / end。
这不是困扰我的事情。
答案 5 :(得分:3)
如果非常糟糕,我可能会为新命名空间中最常用的算法创建一堆模板:
namespace my_ranged_algorithms {
// Metafunction for extracting an appropriate iterator from
// the container type
template <typename T>
struct get_iterator_type_for;
// For vectors
template <typename T>
struct get_iterator_type_for<std::vector<T> > {
typedef typename std::vector<T>::iterator type;
};
template <typename T>
struct get_iterator_type_for<std::vector<T> const> {
typedef typename std::vector<T>::const_iterator type;
};
// For C arrays
template <typename T, size_t N>
struct get_iterator_type_for<T(&)[N]> {
typedef T* type;
};
// Generic begin() and end() wrappers
// For all standard containers
template <typename Cont>
typename get_iterator_type_for<Cont>::type begin(Cont& c) {
return c.begin();
}
template <typename Cont>
typename get_iterator_type_for<Cont>::type end(Cont& c) {
return c.end();
}
// For C arrays
template <typename T, size_t N>
typename get_iterator_type_for<T (&)[N]>::type begin(T (&c)[N]) {
return c;
}
template <typename T, size_t N>
typename get_iterator_type_for<T (&)[N]>::type end(T (&c)[N]) {
return c + N;
}
// Finally, the actual algorithm wrappers
// copy
template <typename Cont, typename OutIter>
OutIter copy(Cont& from, OutIter to) {
return std::copy(begin(from), end(from), to);
}
// remove
template <typename Cont, typename T>
typename get_iterator_type_for<Cont>::type remove(Cont& from, T x) {
return std::remove(begin(from), end(from), x);
}
// etc.
};
然后像这样打电话给他们:
vector<int> a, b;
using namespace my_ranged_algorithms;
copy(a, back_inserter(b));
b.erase(remove(b, 42), b.end()); // Remember to call erase() after remove()!
答案 6 :(得分:3)
This nice presentation [PDF]关于可能的未来解决方案最近与reddit相关联。它讨论了如何使用范围概念完全替换迭代器。
答案 7 :(得分:1)
boost :: range_ex将在c ++ 0x之前解决这个问题。
在此期间自己写几个包装并不难。