【问题标题】:Why isn't std::string::max_size a compile-time constant?为什么 std::string::max_size 不是编译时常量?
【发布时间】:2012-10-19 17:16:54
【问题描述】:

std::string 提供了一个max_size() 方法来确定它可以包含的最大元素数。

但是,一般来说,要计算出字符串的最大长度,程序员必须创建一个(可能为空的)字符串对象。

如果这个类不需要程序员提供任何信息,为什么max_size() 不能作为编译时常量使用?字符串计算其最大大小是否需要某种运行时信息?

【问题讨论】:

  • 您需要创建一个空字符串的逻辑不成立(因为底层分配器持有此信息)。 max_size() 也不是一个常数值。它是当前可以分配的最大值(运行时取决于分配器的状态)。
  • @Loki:你能为你的陈述提供参考吗?我问是因为我很确定你错了(max_size 应用于字符串;分配器是另一回事)。
  • @Nemo:标准中没有任何内容说它是恒定的。不过,在某些实现中它可能是恒定的。 (我在这里假设 -> )如果标准委员会希望它成为一个常量,他们会使其成为像 std::string::npos 这样的 const 成员变量,但为了提供更多的灵活性机会,它是一个方法。
  • @LokiAstari:“如果标准委员会想要它......他们会......”我猜当他们忘记声明std::vector 的内存是连续的时你不在。那么异常规范呢?他们不是神,他们会犯错误。 C++03 标准只说 (23.1) “size() of the maximum possible container”并且它应该有 O(1)。这很模糊,IYAM,并且留下了很多猜测它的含义的空间。

标签: c++ string compile-time-constant


【解决方案1】:

一个原因是max_size 函数根本不是很有用,委员会认为尝试修复它不值得。所以它就保持原样,因为它是文档化界面的一部分。

参见库缺陷报告 #197:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3440.html#197

max_size() 对于很多事情都没有用,现有的措辞对于 max_size() 可以用于的少数情况来说已经足够清楚了。更改现有措辞的任何尝试都不是改进。

【讨论】:

  • +1。这确实是一个非常无用的功能。 std::string::max_size() 返回的是如果有足够的内存,这是它可能持有的最大字符串长度。惊讶于这里有这么多不正确的答案。
【解决方案2】:

std::string::max_size() 在后台调用std::allocator::max_size()。

根据标准,20.9.6.1.10:

size_type max_size() const noexcept;

返回:调用 allocate(N,0) 可能成功的最大值 N。

(另见:allocator::max_size)

理论上,分配器实现可以计算出它可以通过系统调用分配的内存块的最大大小。这将有助于确定特定进程内字符串的最大可能大小。

【讨论】:

  • 标准不要求字符串的max_size调用分配器的max_size。标准对string 的描述参考了第23.1 节中的“容器要求”,它将max_size 定义为“最大可能容器的size()”。它根本不涉及分配器,所以这个答案是完全错误的。
【解决方案3】:

对max_size() 的调用被委托给用于容器的分配器。

理论上,一个非常聪明的分配器可以在运行时计算它的max_size,例如取决于可用的 RAM。

【讨论】:

  • 不,根据标准,它不委派给分配器。也许它在您的特定实现中,但这无关紧要。引用规范中关于将调用委托给其分配器的容器的任何内容,我将删除我的反对票。
  • @Nemo:是的,string::max_size() 不是标准要求的。我说的是一种可能的实现方式。
【解决方案4】:

这也应该有效:

enum : std::string::size_type {
    npos     = std::string::size_type(-1),
    max_size = npos - 1
};

【讨论】:

  • 你所暗示的已经作为 std::string::npos 存在,这与 max_size 不同。
  • 此外,x86 上的 max_size 将导致“最多”size_type(-2),因为 size_type(-1) 被视为无效大小 (npos)。
  • @leetNightshade 确实如此。修好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 2016-01-21
  • 2012-08-31
  • 2012-09-07
相关资源
最近更新 更多