为什么 stoi 不允许 std::basic_string 作为输入?

Why doesn't stoi allow std::basic_string as an input?

提问人:Dmitry Kuzminov 提问时间:8/1/2023 更新时间:8/1/2023 访问量:165

问:

为了提高性能,我正在尝试用自定义专用化来替换标准分配器,其中我用自定义分配器替换了标准分配器。有一件事让我感到惊讶:函数类需要不断引用 (或 ) 作为输入,因此这些函数不适用于其他专用化。但从逻辑上讲,这些函数不应该关心内存是如何分配的;因此,他们的签名看起来过于有限。std::stringstd::basic_stringstd::stoistd::stringstd::wstring

虽然我可以使用 the 从任何类似字符串的数据中读取整数,但我仍然想知道是否有原因以这种方式设计,以及是否有其他 STL 函数旨在与模板一起使用。std::from_charsstd::stoistd::basic_string

C++ STDStel STOI

评论

2赞 alfC 8/1/2023
令我惊讶的是,一开始就没有定义。std::string_view
3赞 康桓瑋 8/1/2023
看起来这可能是一个标准缺陷,因为它支持也很有意义。但是对于 C++17,应该完全替换为 ,所以我看不出它真正需要修复的原因。std::pmr::stringstoifrom_chars
0赞 Remy Lebeau 8/1/2023
@alfC 不保证以 null 结尾,但在内部调用的 C 函数需要以 null 结尾的字符串。std::string_view
0赞 alfC 8/1/2023
@RemyLebeau,我明白了,我不知道这些函数正在调用相应的 c 函数。无论如何这很奇怪,因为 std::string 中间可以有一个 null 字符。我想这很好,因为空字符从来都不是整数的一部分。
0赞 alfC 8/1/2023
对于 OP 来说,似乎没有一个好的解决方案:要么调用底层 c 函数,要么从你的自定义到 .reinterpret_castbasic_stringstd::string const&

答:

-1赞 273K 8/1/2023 #1

因为它只是 C 的代理函数,所以在调用 [1] [2] 后将其错误转换为 C++ 异常std::strtol()

std::strtol(str.c_str(), &ptr, base)

这只需要 ,null 结尾的 char 数组,因此不接受其他专用化。char*char_typestd::basic_string

您可以使用自定义分配器重载,但必须将其称为不带命名空间限定:strtolstd::basic_stringstd::

using std::stoi;

int stoi(const mystring& str, std::size_t* pos = nullptr, int base = 10) {
  char *ptr;
  const long ret = std::strtol(str.c_str(), &ptr, base);

  // Required checks and throwing exceptions here

  if (pos)
    pos = ptr - str.c_str();
  return static_cast<int>(ret);
}

至于 ,它不需要引用以 null 结尾的字符串,因此它没有 并且它不适合 。std::string_viewstd::string_view::c_str()data()std::strtol()

评论

1赞 L. F. 8/1/2023
重点是,对于 ..c_str()basic_string
1赞 L. F. 8/1/2023
对不起,我的意思是用于 .当然,必须是 (或 )。std::basic_string<char, std::char_traits<char>, Alloc>Allocstd::allocator<char>char_typecharwchar_t
2赞 Remy Lebeau 8/1/2023
@273K您的回答声称,因为需要一个以 null 结尾的字符串,不可能接受 的其他专用化,这根本不是真的。在这种情况下,被询问的专业化是在分配器上,而不是字符类型上。由于特别要求,因此不能使用自定义分配器/与自定义分配器一起使用的专用化,即使使用它就可以了strtol()char*stoi()basic_stringstoi()std::(w)stringbasic_stringcharwchar_tstoi()strtol()
1赞 Remy Lebeau 8/1/2023
@273K 你回答的前半部分显然没有谈到.您答案的后半部分在技术上是正确的,但不适用于 OP 提出的问题。所以基本上,你的整个答案都是错误的,需要修复或删除。string_view
2赞 Remy Lebeau 8/1/2023
@273K我不是来善良的。这是一个问答网站。我在这里回答问题,并确保其他答案准确并适用于所提出的问题。您的回答没有充分或正确地解决 OP 的实际问题。