为什么`std :: sto` ...系列不是模板?

Fre*_*ios 19 c++ c++11

我不知道是否有一个原因的std::sto系列(例如std::stoi,std::stol)不是一个函数模板,这样的:

template<typename T>
T sto(std::string const & str, std::size_t *pos = 0, int base = 10);
Run Code Online (Sandbox Code Playgroud)

然后:

template<>
int sto<int>(std::string const & str, std::size_t *pos, int base)
{
    // do the stuff.
}

template<>
long sto<long>(std::string const & str, std::size_t *pos, int base)
{
    // do the stuff.
}

/* etc. */
Run Code Online (Sandbox Code Playgroud)

在我看来,这将是一个更好的设计,因为目前,当我必须转换用户想要的任何数值的字符串时,我必须手动管理每个案例.

有没有理由没有这样的模板功能?是否有一个假定的选择,或者这样做是否就是这样?

Mar*_* Ba 11

在cppref查看这些函数描述,我注意到以下内容:

...解释字符串str中的有符号整数值.

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

以及strolC++中也提供的"C"标准函数.

进一步阅读,我们看到:(对于c ++ sto*函数):

返回值

字符串转换为指定的有符号整数类型.

例外

  • std::invalid_argument 如果不能进行转换
  • std::out_of_range 如果转换后的值超出结果类型的范围,或者基础函数(std :: strtol或std :: strtoll)将errno设置为ERANGE.

虽然我没有这方面的原始资源,并且确实从未使用过这些函数,但我:

TL; DR:这些函数是C++ - 围绕已有的C/C++函数的包装strtol*- 所以它们尽可能接近这些函数.


que*_*atl 7

I have to manage manually each case. Is there a reason to not have such a template function?

如果遇到这样的问题,Eric Lippert(C#)通常会说些什么:

如果缺少某个功能,那么它就会丢失,因为还没有人实现它.这是因为其他人之前还没有想过,或者因为它被认为不值得付出努力,或者因为它在发布当前版本之前无法完成".

在这里,我想这是"不值得"的部分,但我既没有问过委员会,也没有设法在旧问题和常见问题中找到任何答案.我没有花太多时间搜索.

我这样说是因为我认为这些函数中最常见的功能(如果不是全部的话)已经包含在流类中,比如istringstream.就像cin/ etc一样,这个也有operator >>所有基本数字类型(以及更多)的全部重载.

此外,像std::hex(std :: setbase)这样的流操纵器已经解决了将各种类型相关的配置参数传递给实际转换函数的问题.混合功能签名没有问题(比如DavidHaim在他的回答中提到的那些).这只是一个单一的operator>>.

所以..因为如果我们有它streams,如果我们已经可以用简单的字符串读取数字/ etc foo >> bar >> setbase(42) >> baz >> ...,那么我认为为旧的C运行时函数添加更复杂的层是不值得的.

尽管如此,没有证据证明.只是一种预感.


Dav*_*aim 5

模板专业化的问题是专业化要求您匹配原始模板函数签名,因此每个专业化必须实现接口(string,pos,base).

如果你想要一些不遵循这个界面的其他类型,你就遇到了麻烦.

假设,在未来,我们希望拥有sto<std::pair<int,int>>.我们想要posbase第一个和第二个字符串整数.我们希望签名是以string,pos1,base1,pos2,base2.的形式.由于sto签名已经设定,我们无法做到.

你总是可以std::sto*用你的sto整数类型的实现包装,但你不能反过来这样做.