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

时间:2016-06-20 11:05:46

标签: c++ c++11

我想知道std::sto系列(例如std::stoistd::stol)是不是函数模板的原因是这样的:

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

然后:

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. */

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

有没有理由没有这样的模板功能?是假设的选择,还是这样做?

5 个答案:

答案 0 :(得分:11)

查看description of these functions at cppref,我注意到以下内容:

  

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

     

1)拨打$('#button').removeAttr('disabled'); ...

std::strtol(str.c_str(), &ptr, base) a&#34; C&#34;标准函数,也可以在C ++中使用。

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

  

返回值

     

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

     

例外

     
      如果无法执行转换,则
  • sto*
  •   
  • std::invalid_argument如果转换后的值超出结果类型范围或基础函数(std :: strtol或   std :: strtoll)将errno设置为ERANGE。
  •   

因此虽然我没有这方面的原始资料,并且确实从未使用过这些函数,但我会猜测

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

答案 1 :(得分:7)

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

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

  

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

在这里,我猜它不值得&#34;部分,但我既没有问过委员会,也没有设法在旧问题和常见问题中找到任何答案。我没有花太多时间搜索。

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

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

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

虽然没有证明。只是预感。

答案 2 :(得分:5)

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

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

假设将来我们希望sto<std::pair<int,int>>。对于第一个和第二个字符串化整数,我们希望posbase。我们希望签名采用string,pos1,base1,pos2,base2的形式。由于sto签名已经设置,我们无法做到。

对于整数类型,您始终可以在std::sto*的实现中包装sto,但不能以相反的方式执行此操作。

答案 3 :(得分:4)

这些功能的目的是为常见情况提供简单转换。它们不是用作通用转换套件。 std::ostringstream对于那种事情要好得多。

答案 4 :(得分:1)

  

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

不,它不会。模板目标(故意将T-MP分开)是来替换重载;你应该总是喜欢重载到模板。实际上,这是已经为你做的事情!在候选函数和可能的模板瞬时之间,前者将是首选的。使用语言功能是不好的。

我看不出模板是如何帮助的。无论用户决定输入什么类型,在运行时都不会知道它,并且在编译时推导出模板类型。 C ++是一种静态类型语言。在这种情况下,模板只会在正常的函数重载上添加一个不需要的复杂层。