【问题标题】:Size of unknown container未知容器大小
【发布时间】:2015-10-25 11:14:00
【问题描述】:

我一直在阅读,使用此代码不太好:

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() 的替代品是什么,适用于所有容器,包括普通数组?

【问题讨论】:

  • 您可以尝试滚动您自己的模板化 size() 函数,并专门针对原始 c 样式数组。
  • std::size 但直到 C++ 17
  • 您将在 C++17 中获得 std::size(my_vector)。目前没有。
  • YMMV,但我不再担心支持所有容器类型:您只需要四个容器:vector&lt;&gt;unordered_map&lt;&gt;deque&lt;&gt;unordered_set&lt;&gt; 按此顺序排列。其中,只有vector&lt;&gt; 是一般的主力,其他的只在特殊情况下有用。最重要的是,你永远不应该使用list&lt;&gt;forward_list&lt;&gt;,在所有情况下都可以用vector&lt;&gt; 替换,vector&lt;&gt; 会明显更快。也就是说,超过 90% 的容器应该是 vector&lt;&gt;,而特殊情况无论如何都是特殊的。

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


【解决方案1】:

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

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

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

遗憾的是,没有 std::size 作为 std::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;
    }
}

正如 cmets 中所指出的,一个非成员 size() 函数被添加到 working paper for C++17 中(参见 24.3 [iterator.synoposis] 中的概要底部)。 N4280 是提出更改的论文。本文还提出了函数empty()data(),它们也被添加了。所有这些函数都在&lt;iterator&gt; 中声明。

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 2016-03-03
  • 1970-01-01
相关资源
最近更新 更多