为什么C ++没有用C ++元素/样式重新实现C标准函数?

时间:2022-01-05 21:17:30

For a specific example, consider atoi(const std::string &). This is very frustrating, since we as programmers would need to use it so much.

有关具体示例,请考虑atoi(con​​st std :: string&)。这非常令人沮丧,因为我们作为程序员需要使用它。

  1. More general question is why does not C++ standard library reimplement the standard C libraries with C++ string,C++ vector or other C++ standard element rather than to preserve the old C standard libraries and force us use the old char * interface?

    更一般的问题是为什么C ++标准库没有用C ++字符串,C ++向量或其他C ++标准元素重新实现标准C库而不是保留旧的C标准库并迫使我们使用旧的char *接口?

    Its time consuming and the code to translate data types between these two interfaces is not easy to be elegant.

    它耗时并且在这两个接口之间转换数据类型的代码并不容易优雅。

  2. Is it for compatible reason,considering there was much more legacy C code than these days and preserving these C standard interfaces would make translation from C code to C++ much easier?

    这是出于兼容的原因,考虑到比现在有更多的遗留C代码,保留这些C标准接口会使从C代码到C ++的转换更容易吗?

  3. In addition,I have heard many other libraries available for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?

    另外,我听说过许多其他可用于C ++的库对STL进行了大量的增强和扩展。那么库是否支持这些功能呢?

PS: Considering much more answers to the first specific question, I edit a lot to clarify the question to outline the questions that I am much more curious to ask.

PS:考虑到第一个具体问题的更多答案,我编辑了很多来澄清问题,以概述我更加好奇的问题。

10 个解决方案

#1


14  

Another more general question is why do not STL reimplementate all the standard C libraries

另一个更普遍的问题是为什么STL不重新实现所有标准C库

Because the old C libraries do the trick. The C++ standard library only re-implements existing functionality if they can do it significantly better than the old version. And for some parts of the C library, the benefit of writing new C++-implementations just isn't big enough to justify the extra standardization work.

因为旧的C库可以解决问题。如果C ++标准库可以比旧版本更好地执行它,则它只重新实现现有功能。而对于C库的某些部分,编写新C ++的好处 - 实现并不足以证明额外的标准化工作是正确的。

As for atoi and the like, there are new versions of these in the C++ standard library, in the std::stringstream class.

至于atoi等,在std :: stringstream类的C ++标准库中有这些新版本。

To convert from a type T to a type U:

要从类型T转换为类型U:

T in;
U out;
std::stringstream sstr(in);
sstr >> out;

As with the rest of the IOStream library, it's not perfect, it's pretty verbose, it's impressively slow and so on, but it works, and usually it is good enough. It can handle integers of all sizes, floating-point values, C and C++ strings and any other object which defines the operator <<.

与IOStream库的其余部分一样,它并不完美,它非常冗长,速度非常慢,等等,但它确实有效,而且通常它足够好。它可以处理所有大小的整数,浮点值,C和C ++字符串以及定义运算符< <的任何其他对象。< p>

EDIT:In addition,I have heard many other libraries avaliable for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?

编辑:此外,我听说许多其他可用于C ++的库对STL进行了大量的增强和扩展。那么库是否支持这些功能?

Boost has a boost::lexical_cast which wraps std::stringstream. With that function, you can write the above as:

Boost有一个boost :: lexical_cast,它包装了std :: stringstream。使用该功能,您可以将上述内容编写为:

U out = boost::lexical_cast<U>(in);

#2


7  

Even in C, using atoi isn't a good thing to do for converting user input. It doesn't provide error checking at all. Providing a C++ version of it wouldn't be all that useful - considering that it wouldn't throw and do anything, you can just pass .c_str() to it and use it.

即使在C语言中,使用atoi对于转换用户输入也不是一件好事。它根本不提供错误检查。提供它的C ++版本并不是那么有用 - 考虑到它不会抛出任何东西,你可以将.c_str()传递给它并使用它。

Instead you should use strtol in C code, which does do error checking. In C++03, you can use stringstreams to do the same, but their use is error-prone: What exactly do you need to check for? .bad(), .fail(), or .eof()? How do you eat up remaining whitespace? What about formatting flags? Such questions shouldn't bother the average user, that just want to convert his string. boost::lexical_cast does do a good job, but incidentally, C++0x adds utility functions to facilitate fast and safe conversions, through C++ wrappers that can throw if conversion failed:

相反,你应该在C代码中使用strtol,它确实进行了错误检查。在C ++ 03中,你可以使用stringstreams来做同样的事情,但是它们的使用容易出错:你究竟需要检查什么? .bad(),. fail()或.eof()?你怎么吃剩余的空白?格式化标志怎么样?这样的问题不应该打扰普通用户,只想转换他的字符串。 boost :: lexical_cast确实做得很好,但顺便提一句,C ++ 0x添加了实用程序函数,以便通过C ++包装器来实现快速安全的转换,如果转换失败则可以抛出:

int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull(str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

效果:前两个函数调用strtol(str.c_str(),ptr,base),最后三个函数调用strtoul(str.c_str(),ptr,base),strtoll(str.c_str(),ptr,base )和strtoull(str.c_str(),ptr,base)。每个函数返回转换后的结果(如果有)。参数ptr指定一个指向函数内部对象的指针,该对象用于确定在* idx中存储的内容。如果函数没有抛出异常并且idx!= 0,则函数在* idx中存储str的第一个未转换元素的索引。

Returns: the converted result.

返回:转换后的结果。

Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type.

抛出:invalid_argument如果strtol,strtoul,strtoll或strtoull报告不能执行转换。如果转换后的值超出返回类型的可表示值范围,则抛出out_of_range。

#3


5  

There's no good way to know if atoi fails. It always returns an integer. Is that integer a valid conversion? Or is the 0 or -1 or whatever indicating an error? Yes it could throw an exception, but that would change the original contract, and you'd have to update all your code to catch the exception (which is what the OP is complaining about).

没有好办法知道atoi是否失败了。它总是返回一个整数。该整数是有效转换吗?或者是0或-1或其他表示错误的?是的,它可能会抛出异常,但这会改变原始合同,并且您必须更新所有代码以捕获异常(这是OP正在抱怨的内容)。

If translation is too time consuming, write your own atoi:

如果翻译过于耗时,请编写自己的atoi:

int atoi(const std::string& str)
{
    std::istringstream stream(str);
    int ret = 0;
    stream >> ret;
    return ret;
}

#4


4  

I see that solutions are offered that use std::stringstream or std::istringstream. This might be perfectly OK for single threaded applications but if an application has lots of threads and often calls atoi(const std::string& str) implemented in this way that will result in performance degradation.

我看到提供了使用std :: stringstream或std :: istringstream的解决方案。对于单线程应用程序来说这可能是完全正常的,但是如果应用程序有很多线程并且经常调用以这种方式实现的atoi(con​​st std :: string&str),这将导致性能下降。

Read this discussion for example: http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html. And see a backtrace of the constructor of std::istringstream:

请阅读此讨论,例如:http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html。并查看std :: istringstream的构造函数的回溯:

#0  0x200000007eb77810:0 in pthread_mutex_unlock+0x10 ()
   from /usr/lib/hpux32/libc.so.1
#1  0x200000007ef22590 in std::locale::locale (this=0x7fffeee8)
    at gthr-default.h:704
#2  0x200000007ef29500 in std::ios_base::ios_base (this=<not available>)
    at /tmp/gcc-4.3.1.tar.gz/gcc-4.3.1/libstdc++-v3/src/ios.cc:83
#3  0x200000007ee8cd70 in std::basic_istringstream<char,std::char_traits<char>,std::allocator<char> >::basic_istringstream (this=0x7fffee4c,
    __str=@0x7fffee44, __mode=_S_in) at basic_ios.h:456
#4  0x4000f70:0 in main () at main.cpp:7

So every time you enter atoi() and create a local varibale of type std::stringstream you will lock a global mutex and in a multithreaded application it is likely to result in waiting on this mutex.

因此,每次输入atoi()并创建std :: stringstream类型的本地变量时,您将锁定全局互斥锁,并且在多线程应用程序中,可能会导致等待此互斥锁。

So, it's better in a multithreaded application not to use std::stringstream. For example simply call atoi(const char*):

因此,在多线程应用程序中最好不要使用std :: stringstream。例如,只需调用atoi(con​​st char *):

inline int atoi(const std::string& str)
{
    return atoi(str.c_str());
}

#5


3  

For your example, you've got two options:

举个例子,你有两个选择:

std::string mystring("4");
int myint = atoi(mystring.c_str());

Or something like:

或类似的东西:

std::string mystring("4");
std::istringstream buffer(mystring);
int myint = 0;
buffer >> myint;

The second option gives you better error management than the first.

第二个选项为您提供比第一个更好的错误管理。

#6


1  

You can write a more generic string to number convert as such:

您可以编写一个更通用的字符串来进行数字转换:

template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);

#7


1  

For conversions I find simplest to use boost's lexical_cast (except it might be too rigorously checking the validity of the conversions of string to other types).

对于转换,我发现最简单的方法是使用boost的lexical_cast(除非它可能过于严格地检查字符串转换为其他类型的有效性)。

It surely isn't very fast (it just uses std::stringstream under the hood, but significantly more convenient), but performance is often not needed where you convert values (e.g to create error output messages and such). (If you do lots of these conversions and need extreme performance, chances are you are doing something wrong and shouldn't be performing any conversions at all.)

它肯定不是很快(它只是在引擎盖下使用std :: stringstream,但显然更方便),但在转换值时通常不需要性能(例如创建错误输出消息等)。 (如果你做了很多这些转换并且需要极高的性能,那么你可能做错了什么,而且根本不应该进行任何转换。)

#8


1  

Because the old C libraries still work with standard C++ types, with a very little bit of adaptation. You can easily change a const char * to a std::string with a constructor, and change back with std::string::c_str(). In your example, with std::string s, just call atoi(s.c_str()) and you're fine. As long as you can switch back and forth easily there's no need to add new functionality.

因为旧的C库仍然可以使用标准C ++类型,只需要很少的适应性。您可以使用构造函数轻松地将const char *更改为std :: string,然后使用std :: string :: c_str()进行更改。在你的例子中,使用std :: string s,只需调用atoi(s.c_str())就可以了。只要您可以轻松来回切换,就无需添加新功能。

I'm not coming up with C functions that work on arrays and not container classes, except for things like qsort() and bsearch(), and the STL has better ways to do such things. If you had specific examples, I could consider them.

我没有提出在数组上工作的C函数而不是容器类,除了像qsort()和bsearch()这样的东西,STL有更好的方法来做这些事情。如果你有具体的例子,我可以考虑一下。

C++ does need to support the old C libraries for compatibility purposes, but the tendency is to provide new techniques where warranted, and provide interfaces for the old functions when there isn't much of an improvement. For example, the Boost lexical_cast is an improvement over such functions as atoi() and strtol(), much as the standard C++ string is an improvement over the C way of doing things. (Sometimes this is subjective. While C++ streams have considerable advantages over the C I/O functions, there's times when I'd rather drop back to the C way of doing things. Some parts of the C++ standard library are excellent, and some parts, well, aren't.)

C ++确实需要支持旧的C库以实现兼容性,但趋势是提供有保证的新技术,并在没有太多改进时为旧函数提供接口。例如,Boost lexical_cast是对atoi()和strtol()等函数的改进,就像标准C ++字符串是对C语言的改进一样。 (有时候这是主观的。虽然C ++流比CI / O函数有相当大的优势,但有时候我宁愿退回到C的做事方式.C ++标准库的某些部分非常好,有些部分,好吧,不是。)

#9


0  

There are all sorts of ways to parse a number from a string, atoi can easily be used with a std::string via atoi(std.c_str()) if you really want, but atoi has a bad interface because there is no sure way to determine if an error occurred during parsing.

有各种各样的方法来解析字符串中的数字,如果你真的想要atoi可以很容易地通过atoi(std.c_str())与std :: string一起使用,但atoi有一个糟糕的接口,因为没有确定确定解析过程中是否发生错误的方法。

Here's one slightly more modern C++ way to get an int from a std::string:

这是从std :: string获取int的一种稍微更现代的C ++方法:

std::istringstream tmpstream(str);
if (tmpstream >> intvar)
{
    // ... success! ...
}

#10


0  

The tongue in cheek answer is: Because STL is a half-hearted attempt to show how powerful C++ templates could be. Before they got to each corner of the problem space, time was up.

脸颊上的答案是:因为STL是一个半心半意的尝试来展示C ++模板的强大功能。在他们到达问题空间的每个角落之前,时间已经过去了。

There are two reasons: Creating an API takes time and effort. Create a good API takes a lot of time and a huge effort. Creating a great API takes an insane amount of time and an incredible effort. When the STL was created, OO was still pretty new to the C++ people. They didn't have the ideas how to make fluent and simple API. Today, we think iterators are so 1990 but at the time, people thought "Bloody hell, why would I need that? for (int i=0; i<...) has been good enough for three decades!"

有两个原因:创建API需要时间和精力。创建一个好的API需要花费大量的时间和巨大的努力。创建一个出色的API需要花费大量的时间和不可思议的努力。在创建STL时,OO对于C ++人员来说仍然是一个新手。他们没有如何制作流畅简单的API的想法。今天,我们认为迭代器是如此1990年,但在当时,人们认为“血腥地狱,为什么我需要它?因为(int i = 0; i <...)已经足够好了三十年!”

So STL didn't became the great, fluent API. This isn't all C++ fault because you can make good APIs with C++. But it was the first attempt to do that and it shows. Before the API could mature, it was turned into a standard and all the ugly shortcomings were set into stone. And on top of this, there was all this legacy code and all the libraries which already could do everything, so the pressure wasn't really there.

所以STL并没有成为优秀,流畅的API。这不是所有的C ++错误,因为你可以用C ++制作好的API。但这是第一次尝试这样做,它表明了。在API成熟之前,它已经变成了一个标准,并且所有丑陋的缺点都被置之不理。除此之外,还有所有这些遗留代码和所有已经可以完成所有工作的库,所以压力并不是真的存在。

To solve your misery, give up on STL and have a look at the successors: Try boost and maybe Qt. Yeah, Qt is a UI library but it also has a pretty good standard library.

为了解决你的痛苦,放弃STL并看看接班人:尝试提升,也许Qt。是的,Qt是一个UI库,但它也有一个非常好的标准库。

#1


14  

Another more general question is why do not STL reimplementate all the standard C libraries

另一个更普遍的问题是为什么STL不重新实现所有标准C库

Because the old C libraries do the trick. The C++ standard library only re-implements existing functionality if they can do it significantly better than the old version. And for some parts of the C library, the benefit of writing new C++-implementations just isn't big enough to justify the extra standardization work.

因为旧的C库可以解决问题。如果C ++标准库可以比旧版本更好地执行它,则它只重新实现现有功能。而对于C库的某些部分,编写新C ++的好处 - 实现并不足以证明额外的标准化工作是正确的。

As for atoi and the like, there are new versions of these in the C++ standard library, in the std::stringstream class.

至于atoi等,在std :: stringstream类的C ++标准库中有这些新版本。

To convert from a type T to a type U:

要从类型T转换为类型U:

T in;
U out;
std::stringstream sstr(in);
sstr >> out;

As with the rest of the IOStream library, it's not perfect, it's pretty verbose, it's impressively slow and so on, but it works, and usually it is good enough. It can handle integers of all sizes, floating-point values, C and C++ strings and any other object which defines the operator <<.

与IOStream库的其余部分一样,它并不完美,它非常冗长,速度非常慢,等等,但它确实有效,而且通常它足够好。它可以处理所有大小的整数,浮点值,C和C ++字符串以及定义运算符< <的任何其他对象。< p>

EDIT:In addition,I have heard many other libraries avaliable for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?

编辑:此外,我听说许多其他可用于C ++的库对STL进行了大量的增强和扩展。那么库是否支持这些功能?

Boost has a boost::lexical_cast which wraps std::stringstream. With that function, you can write the above as:

Boost有一个boost :: lexical_cast,它包装了std :: stringstream。使用该功能,您可以将上述内容编写为:

U out = boost::lexical_cast<U>(in);

#2


7  

Even in C, using atoi isn't a good thing to do for converting user input. It doesn't provide error checking at all. Providing a C++ version of it wouldn't be all that useful - considering that it wouldn't throw and do anything, you can just pass .c_str() to it and use it.

即使在C语言中,使用atoi对于转换用户输入也不是一件好事。它根本不提供错误检查。提供它的C ++版本并不是那么有用 - 考虑到它不会抛出任何东西,你可以将.c_str()传递给它并使用它。

Instead you should use strtol in C code, which does do error checking. In C++03, you can use stringstreams to do the same, but their use is error-prone: What exactly do you need to check for? .bad(), .fail(), or .eof()? How do you eat up remaining whitespace? What about formatting flags? Such questions shouldn't bother the average user, that just want to convert his string. boost::lexical_cast does do a good job, but incidentally, C++0x adds utility functions to facilitate fast and safe conversions, through C++ wrappers that can throw if conversion failed:

相反,你应该在C代码中使用strtol,它确实进行了错误检查。在C ++ 03中,你可以使用stringstreams来做同样的事情,但是它们的使用容易出错:你究竟需要检查什么? .bad(),. fail()或.eof()?你怎么吃剩余的空白?格式化标志怎么样?这样的问题不应该打扰普通用户,只想转换他的字符串。 boost :: lexical_cast确实做得很好,但顺便提一句,C ++ 0x添加了实用程序函数,以便通过C ++包装器来实现快速安全的转换,如果转换失败则可以抛出:

int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull(str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

效果:前两个函数调用strtol(str.c_str(),ptr,base),最后三个函数调用strtoul(str.c_str(),ptr,base),strtoll(str.c_str(),ptr,base )和strtoull(str.c_str(),ptr,base)。每个函数返回转换后的结果(如果有)。参数ptr指定一个指向函数内部对象的指针,该对象用于确定在* idx中存储的内容。如果函数没有抛出异常并且idx!= 0,则函数在* idx中存储str的第一个未转换元素的索引。

Returns: the converted result.

返回:转换后的结果。

Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type.

抛出:invalid_argument如果strtol,strtoul,strtoll或strtoull报告不能执行转换。如果转换后的值超出返回类型的可表示值范围,则抛出out_of_range。

#3


5  

There's no good way to know if atoi fails. It always returns an integer. Is that integer a valid conversion? Or is the 0 or -1 or whatever indicating an error? Yes it could throw an exception, but that would change the original contract, and you'd have to update all your code to catch the exception (which is what the OP is complaining about).

没有好办法知道atoi是否失败了。它总是返回一个整数。该整数是有效转换吗?或者是0或-1或其他表示错误的?是的,它可能会抛出异常,但这会改变原始合同,并且您必须更新所有代码以捕获异常(这是OP正在抱怨的内容)。

If translation is too time consuming, write your own atoi:

如果翻译过于耗时,请编写自己的atoi:

int atoi(const std::string& str)
{
    std::istringstream stream(str);
    int ret = 0;
    stream >> ret;
    return ret;
}

#4


4  

I see that solutions are offered that use std::stringstream or std::istringstream. This might be perfectly OK for single threaded applications but if an application has lots of threads and often calls atoi(const std::string& str) implemented in this way that will result in performance degradation.

我看到提供了使用std :: stringstream或std :: istringstream的解决方案。对于单线程应用程序来说这可能是完全正常的,但是如果应用程序有很多线程并且经常调用以这种方式实现的atoi(con​​st std :: string&str),这将导致性能下降。

Read this discussion for example: http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html. And see a backtrace of the constructor of std::istringstream:

请阅读此讨论,例如:http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html。并查看std :: istringstream的构造函数的回溯:

#0  0x200000007eb77810:0 in pthread_mutex_unlock+0x10 ()
   from /usr/lib/hpux32/libc.so.1
#1  0x200000007ef22590 in std::locale::locale (this=0x7fffeee8)
    at gthr-default.h:704
#2  0x200000007ef29500 in std::ios_base::ios_base (this=<not available>)
    at /tmp/gcc-4.3.1.tar.gz/gcc-4.3.1/libstdc++-v3/src/ios.cc:83
#3  0x200000007ee8cd70 in std::basic_istringstream<char,std::char_traits<char>,std::allocator<char> >::basic_istringstream (this=0x7fffee4c,
    __str=@0x7fffee44, __mode=_S_in) at basic_ios.h:456
#4  0x4000f70:0 in main () at main.cpp:7

So every time you enter atoi() and create a local varibale of type std::stringstream you will lock a global mutex and in a multithreaded application it is likely to result in waiting on this mutex.

因此,每次输入atoi()并创建std :: stringstream类型的本地变量时,您将锁定全局互斥锁,并且在多线程应用程序中,可能会导致等待此互斥锁。

So, it's better in a multithreaded application not to use std::stringstream. For example simply call atoi(const char*):

因此,在多线程应用程序中最好不要使用std :: stringstream。例如,只需调用atoi(con​​st char *):

inline int atoi(const std::string& str)
{
    return atoi(str.c_str());
}

#5


3  

For your example, you've got two options:

举个例子,你有两个选择:

std::string mystring("4");
int myint = atoi(mystring.c_str());

Or something like:

或类似的东西:

std::string mystring("4");
std::istringstream buffer(mystring);
int myint = 0;
buffer >> myint;

The second option gives you better error management than the first.

第二个选项为您提供比第一个更好的错误管理。

#6


1  

You can write a more generic string to number convert as such:

您可以编写一个更通用的字符串来进行数字转换:

template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);

#7


1  

For conversions I find simplest to use boost's lexical_cast (except it might be too rigorously checking the validity of the conversions of string to other types).

对于转换,我发现最简单的方法是使用boost的lexical_cast(除非它可能过于严格地检查字符串转换为其他类型的有效性)。

It surely isn't very fast (it just uses std::stringstream under the hood, but significantly more convenient), but performance is often not needed where you convert values (e.g to create error output messages and such). (If you do lots of these conversions and need extreme performance, chances are you are doing something wrong and shouldn't be performing any conversions at all.)

它肯定不是很快(它只是在引擎盖下使用std :: stringstream,但显然更方便),但在转换值时通常不需要性能(例如创建错误输出消息等)。 (如果你做了很多这些转换并且需要极高的性能,那么你可能做错了什么,而且根本不应该进行任何转换。)

#8


1  

Because the old C libraries still work with standard C++ types, with a very little bit of adaptation. You can easily change a const char * to a std::string with a constructor, and change back with std::string::c_str(). In your example, with std::string s, just call atoi(s.c_str()) and you're fine. As long as you can switch back and forth easily there's no need to add new functionality.

因为旧的C库仍然可以使用标准C ++类型,只需要很少的适应性。您可以使用构造函数轻松地将const char *更改为std :: string,然后使用std :: string :: c_str()进行更改。在你的例子中,使用std :: string s,只需调用atoi(s.c_str())就可以了。只要您可以轻松来回切换,就无需添加新功能。

I'm not coming up with C functions that work on arrays and not container classes, except for things like qsort() and bsearch(), and the STL has better ways to do such things. If you had specific examples, I could consider them.

我没有提出在数组上工作的C函数而不是容器类,除了像qsort()和bsearch()这样的东西,STL有更好的方法来做这些事情。如果你有具体的例子,我可以考虑一下。

C++ does need to support the old C libraries for compatibility purposes, but the tendency is to provide new techniques where warranted, and provide interfaces for the old functions when there isn't much of an improvement. For example, the Boost lexical_cast is an improvement over such functions as atoi() and strtol(), much as the standard C++ string is an improvement over the C way of doing things. (Sometimes this is subjective. While C++ streams have considerable advantages over the C I/O functions, there's times when I'd rather drop back to the C way of doing things. Some parts of the C++ standard library are excellent, and some parts, well, aren't.)

C ++确实需要支持旧的C库以实现兼容性,但趋势是提供有保证的新技术,并在没有太多改进时为旧函数提供接口。例如,Boost lexical_cast是对atoi()和strtol()等函数的改进,就像标准C ++字符串是对C语言的改进一样。 (有时候这是主观的。虽然C ++流比CI / O函数有相当大的优势,但有时候我宁愿退回到C的做事方式.C ++标准库的某些部分非常好,有些部分,好吧,不是。)

#9


0  

There are all sorts of ways to parse a number from a string, atoi can easily be used with a std::string via atoi(std.c_str()) if you really want, but atoi has a bad interface because there is no sure way to determine if an error occurred during parsing.

有各种各样的方法来解析字符串中的数字,如果你真的想要atoi可以很容易地通过atoi(std.c_str())与std :: string一起使用,但atoi有一个糟糕的接口,因为没有确定确定解析过程中是否发生错误的方法。

Here's one slightly more modern C++ way to get an int from a std::string:

这是从std :: string获取int的一种稍微更现代的C ++方法:

std::istringstream tmpstream(str);
if (tmpstream >> intvar)
{
    // ... success! ...
}

#10


0  

The tongue in cheek answer is: Because STL is a half-hearted attempt to show how powerful C++ templates could be. Before they got to each corner of the problem space, time was up.

脸颊上的答案是:因为STL是一个半心半意的尝试来展示C ++模板的强大功能。在他们到达问题空间的每个角落之前,时间已经过去了。

There are two reasons: Creating an API takes time and effort. Create a good API takes a lot of time and a huge effort. Creating a great API takes an insane amount of time and an incredible effort. When the STL was created, OO was still pretty new to the C++ people. They didn't have the ideas how to make fluent and simple API. Today, we think iterators are so 1990 but at the time, people thought "Bloody hell, why would I need that? for (int i=0; i<...) has been good enough for three decades!"

有两个原因:创建API需要时间和精力。创建一个好的API需要花费大量的时间和巨大的努力。创建一个出色的API需要花费大量的时间和不可思议的努力。在创建STL时,OO对于C ++人员来说仍然是一个新手。他们没有如何制作流畅简单的API的想法。今天,我们认为迭代器是如此1990年,但在当时,人们认为“血腥地狱,为什么我需要它?因为(int i = 0; i <...)已经足够好了三十年!”

So STL didn't became the great, fluent API. This isn't all C++ fault because you can make good APIs with C++. But it was the first attempt to do that and it shows. Before the API could mature, it was turned into a standard and all the ugly shortcomings were set into stone. And on top of this, there was all this legacy code and all the libraries which already could do everything, so the pressure wasn't really there.

所以STL并没有成为优秀,流畅的API。这不是所有的C ++错误,因为你可以用C ++制作好的API。但这是第一次尝试这样做,它表明了。在API成熟之前,它已经变成了一个标准,并且所有丑陋的缺点都被置之不理。除此之外,还有所有这些遗留代码和所有已经可以完成所有工作的库,所以压力并不是真的存在。

To solve your misery, give up on STL and have a look at the successors: Try boost and maybe Qt. Yeah, Qt is a UI library but it also has a pretty good standard library.

为了解决你的痛苦,放弃STL并看看接班人:尝试提升,也许Qt。是的,Qt是一个UI库,但它也有一个非常好的标准库。