qdi*_*dii 4 c++ string optimization std
让我们考虑一下这个片段,请假设a,b,c和d是非空字符串.
std::string a, b, c, d;
d = a + b + c;
Run Code Online (Sandbox Code Playgroud)
当计算这3个std::string实例的总和时 ,标准库实现创建第一个临时std::string对象,在其内部缓冲区中复制a和的连接缓冲区b,然后在临时字符串和之间执行相同的操作c.
一位同事程序员强调,operator+(std::string, std::string)可以定义为返回a 而不是此行为std::string_helper.
这个对象的作用是将实际的连接推迟到它被转换为a的那一刻std::string.显然,operator+(std::string_helper, std::string)将被定义为返回相同的帮助程序,这将"牢记"它有一个额外的串联来执行的事实.
这样的行为可以节省创建n-1临时对象,分配缓冲区,复制它们等的CPU成本.所以我的问题是:为什么它不能像那样工作?我想不出任何缺点或限制.
为什么它不像那样工作?
我只能推测为什么它最初是这样设计的.也许字符串库的设计者根本没有想到它; 也许他们认为额外的类型转换(见下文)可能会使某些情况下的行为过于令人惊讶.它是最古老的C++库之一,我们认为理所当然的许多智慧在过去几十年中根本不存在.
至于为什么它没有被改变为这样工作:它可以通过添加额外的用户定义类型转换来破坏现有代码.隐式转换最多只能涉及一个用户定义的转换.这是由C++ 11,13.3.3.1.2/1指定的:
用户定义的转换序列包括初始标准转换序列,后跟用户定义的转换,然后是第二个标准转换序列.
考虑以下:
struct thingy {
thingy(std::string);
};
void f(thingy);
f(some_string + another_string);
Run Code Online (Sandbox Code Playgroud)
此代码是好的,如果类型some_string + another_string是std::string.这可以thingy通过转换构造函数隐式转换为.但是,如果我们要更改定义operator+以提供另一种类型,那么它将需要两次转换(string_helperto stringto thingy),因此无法编译.
因此,如果字符串构建的速度很重要,则需要使用其他方法,例如串联+=.或者,根据Matthieu的回答,不要担心它,因为C++ 11以不同的方式修复了低效率.
显而易见的答案:因为标准不允许它.它在某些情况下通过引入额外的用户定义转换来影响代码:如果C是具有用户定义的构造函数的类型,std::string则会产生:
C obj = stringA + stringB;
Run Code Online (Sandbox Code Playgroud)
非法.
| 归档时间: |
|
| 查看次数: |
1447 次 |
| 最近记录: |