Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么'std::sto'。。。系列不是模板?_C++_C++11 - Fatal编程技术网

C++ 为什么'std::sto'。。。系列不是模板?

C++ 为什么'std::sto'。。。系列不是模板?,c++,c++11,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); 模板 sto(std::string const&str,std::size\u T*pos=0,int base=10); 然后: template<> int sto<

我想知道为什么
std::sto
系列(例如
std::stoi
std::stol
)不是一个函数模板,比如:

template<typename T>
T sto(std::string const & str, std::size_t *pos = 0, int base = 10);
模板
sto(std::string const&str,std::size\u 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. */
模板
int sto(标准::字符串常量和字符串,标准::大小\u t*pos,整数基)
{
//做这件事。
}
模板
长sto(标准::字符串常量和字符串,标准::大小\u t*pos,整数基)
{
//做这件事。
}
/*等等*/
在我看来,这将是一个更好的设计,因为目前,当我必须将字符串转换为用户想要的任何数值时,我必须手动管理每个案例

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

看看,我注意到以下几点:

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

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

和<代码> StROL< /COD>一个C语言标准函数,C++中也有可用的。

进一步阅读,我们看到:(对于C++ <代码> STO*<代码>函数):

返回值 转换为指定有符号整数类型的字符串

例外情况
  • std::如果无法执行转换,则参数无效
  • std::out_of_range
    如果转换后的值会超出结果类型的范围,或者如果基础函数(std::strtol或 std::strtoll)将errno设置为Errange
因此,虽然我没有这方面的原始来源,而且确实从未使用过这些函数,但我猜:


TL;DR:这些函数是围绕现有C/C++函数的C++-ish包装,因此它们与这些函数尽可能相似。

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

如果您希望有其他类型的接口不遵循此接口,那么您就有麻烦了

假设将来,我们希望有
sto
。对于第一个和第二个字符串化整数,我们需要使用
pos
base
。我们希望签名的形式为
字符串、pos1、base1、pos2、base2
。由于
sto
签名已设置,我们无法执行此操作


sto
的实现中,您可以始终为整型类型包装
std::sto*
,但不能反过来包装

我必须手动管理每个案例。有没有理由不使用这种模板功能?

对于此类问题,Eric Lippert(C#)通常会说一些大致的话:

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

在这里,我想这是“不值得”的部分,但我既没有询问委员会,也没有设法在旧问题和常见问题中找到任何答案。尽管如此,我没有花太多时间搜索

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

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

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


不过没有证据。只是一种预感。

这些函数的目的是为常见情况提供简单的转换。它们不打算作为通用转换套件。
std::ostringstream
更适合这种情况

在我看来,会有更好的设计,因为目前, 当我必须将字符串转换为用户指定的数值时 如果需要,我必须手动管理每个案例

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


< >我不知道模板是如何帮助的。无论用户决定输入什么类型,直到运行时它都不会知道,模板类型是在编译时推导出来的。C++是静态类型的语言。在这种情况下,模板只会增加一个不需要的函数层,而不是正常函数重载。你的意思是
std::stoi
std::stol
,等等?浮点版本没有
base
参数。这些函数调用的“旧”C函数(
strtol
strtoll
,…)可能与保持一致。如果必须编写
sto
而不是
stol
,您会得到什么好处?@molbdnilo:您不允许向
std
添加新的重载,