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

201 Views Asked by At

To increase the performance I'm trying to substitute std::string with custom specializations of std::basic_string where I'm replacing standard allocator with custom ones. One thing surprised me: the std::stoi class of functions requires constant references to std::string (or std::wstring) as an input, so these functions don't work with other specializations. But logically these functions shouldn't care of how the memory is allocated; so their signatures look overly limiting.

While I could use the std::from_chars to read integers from any string-like data, I still wonder whether there was a reason why std::stoi is designed that way, and whether there are other STL functions designed to work with std::basic_string templates.

1

There are 1 best solutions below

12
273K On

Because it's just a proxy function to C std::strtol(), converts its errors to C++ exceptions after a call to [1] [2]

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

that takes only char*, null-terminated char array, hence other char_type specializations of std::basic_string are not accepted.

You can overload strtol for std::basic_string with your custom allocator, but you have to call it w/o std:: namespace qualification:

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);
}

As for std::string_view, it is not required to refer a null-terminated string, thus it does not have std::string_view::c_str() and its data() is not suitable for std::strtol().