【问题标题】:Guarantee that std::container::size_type is a std::size_t保证 std::container::size_type 是 std::size_t
【发布时间】:2018-02-15 22:19:04
【问题描述】:

this question 之后,出于明显的可读性原因,我决定将std::size_t 用作每个容器的size_type。我知道理论上std::container<T>::size_type 可能不是std::size_t,但我认为在我当前和未来的配置中并非如此。

但是,为了避免恶意错误,我在使用它们时会检查类型是否相同。例如:

BOOST_STATIC_ASSERT(boost::is_same< std::vector<double>::size_type , std::size_t >::value);
std::vector<double> x;
/* fill x */
for(std::size_t i = 0; i < x.size(); ++i) { /* do something */ }

代码中的另一个地方,我使用了std::vector&lt;long int&gt;,然后我也检查了:

BOOST_STATIC_ASSERT(boost::is_same< std::vector<long int>::size_type , std::size_t >::value);

然后,哦不!我使用std::vector&lt;std::list&lt;std::string&gt;*&gt;std::vector&lt;std::list&lt;double*&gt;*&gt;,然后我检查:

BOOST_STATIC_ASSERT(boost::is_same< std::vector<std::list<std::string>*>::size_type , std::size_t >::value);
BOOST_STATIC_ASSERT(boost::is_same< std::vector<std::list<double*>*>::size_type , std::size_t >::value);

好的,我想你明白了这个问题。丑陋的线条,难以维护的代码。这是个坏主意。

那么,我的问题是:如果我检查std::vector&lt;any_common_type&gt;::size_typestd::size_t,有没有可能std::vector&lt;another_type&gt;::size_type 不是std::size_t?仅检查单独文件中的一些常见类型以确保我的编译器上的 std::container::size_type 始终为 std::size_t 就足够了吗?

注意:出于兼容性原因,我不使用 C++11。

【问题讨论】:

  • 我同意“为什么?”似乎 size_t 不能小于 vector<..>::size_type;所以容器返回的大小不会不适合 size_t 的风险。
  • 我不知道你的问题的答案(我相信size_type 不会改变),但如果你碰巧遇到size_t 不够大的实现要包含 size_type 的所有值,您的编译器将在您尝试执行的第一次比较时发出警告。
  • 关于 std::vector::size_type 是否取决于类型的问题:如果 sizeof(T) 足够大,有人可能会尝试使用“unsigned short”作为 size_type。我不知道这是否合法——或者为什么有人会为那个麻烦而烦恼——但我认为这是不同 size_type 最现实的场景。
  • 实际上,这不仅仅是一个太小的范围的问题,范围必须相同以避免错误,例如:std::size_t p = x.find(...); 其中npos 如果找不到则返回。通常,npos-1(即类型的最大值)。如果范围不同,可能会导致非常糟糕的错误(我尝试过,当我使用unsigned long int 而不是std::size_t ^^)。
  • 是的,@Caduchon 如果存在这样的函数 - 但 container::find 通常返回一个迭代器,而不是一个索引(并且它不存在于向量中);所以我不认为这是标准容器的问题。

标签: c++ stl c++03 size-t size-type


【解决方案1】:

如果您真的需要这样做,您在问题中遵循的方法似乎是要走的路。

不过,我觉得你太担心了,因为size_t可以处理size_type

如果您发现自己处于一种不太可能的情况,即平台以一种不足以包含size_type 的所有值的方式实现size_t,那么我很确定您会收到一个编译器警告您将尝试执行的任何比较。

'size_t' vs 'container::size_type' 提及:

标准容器将 size_type 定义为 typedef Allocator::size_type (Allocator 是一个模板参数),它用于 std::allocator 通常定义为 size_t (或兼容的 类型)。所以对于标准情况,它们是相同的。


所以,如果我是你,我会对我的编译器在典型情况下的表现充满信心。但是,如果我确实使用了非标准容器,那么我会费心遵循你的 - 正如你所说的那样丑陋 - 方法,将它放在一个文件中,让它在一个隐藏的黑暗角落里完成它的工作。

【讨论】:

    猜你喜欢
    • 2017-12-23
    • 2010-10-29
    • 2014-12-13
    • 2012-09-11
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2019-04-25
    相关资源
    最近更新 更多