未知容器的大小

时间:2015-10-25 11:14:01

标签: c++ c++11 coding-style std

我一直在阅读使用此代码并不是那么好:

std::vector<T> my_vector;
...
std::sort(my_vector.begin(), my_vector.end());

最好将其写为:

std::vector<T> my_vector;
...
std::sort(std::begin(my_vector), std::end(my_vector));

因为std :: begin适用于所有容器,包括普通数组。

my_vector.size()的替代方法是什么,它适用于所有容器,包括普通数组?

1 个答案:

答案 0 :(得分:20)

实际上使用std::begin(my_vector)而不是正确的事情!如果您想要选择自定义点,请使用

using std::begin;
using std::end;
std::sort(begin(cont), end(cont));

此方法尝试使用ADL查找begin(cont),并且在找不到合适的版本时,回退使用std::begin

可悲的是,没有std::sizestd::begin等自定义点的默认值。使用std::distance()

可能会有所作为
std::distance(begin(cont), end(cont));

但是,对于典型的基于节点的容器,或者更一般地说,对于非随机访问迭代器,此方法将遍历元素而不是从存储值获取大小。因此,我认为您想要致电cont.size()。定义合适的定制点是相对简单的:

namespace util {
    template <typename C>
    typename C::difference_type size(C const& c) {
        return c.size();
    }
    template <typename T, std::size_t N>
    std::size_t size(T const(&)[N]) {
        return N;
    }
}

正如评论中指出的那样,working paper for C++17中添加了非成员size()函数(参见24.3 [iterator.synoposis]中的概要底部)。 N4280是提出改变的论文。本文还提出了已添加的函数empty()data()。所有这些函数都在<iterator>中声明。

添加到C ++ 17的版本在返回类型中直接使用decltype()成员上的size()。另外,它声明函数为constexpr

template <typename C>
constexpr auto size(C const& c) -> decltype(c.size()) {
    return c.size();
}