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::strtol或 std::strtoll)将errno设置为Errangestd::out_of_range
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
添加新的重载,