提问人:Mako 提问时间:6/26/2021 更新时间:6/26/2021 访问量:247
C++ 常量参数传递:为什么编译器不自动设置为按引用传递
c++ const argument passing: why compilers do not automatically set to pass-by-reference
问:
我了解到,对于非基元类型的常量参数,将它们作为引用传递到函数中比作为值传递更有效:
效率不高的版本:
void funcA(const std::string myString)
高效版:
void funcA(const std::string&myString)
由于高效版本似乎是一个显而易见的选择,我想知道为什么 C++ 编译器不以这种方式自动优化效率低下的版本?
答:
2赞
rawrex
6/26/2021
#1
即使在副本的情况下也有优化。是的,一般来说,当函数参数按值传递时,编译器需要制作副本(因此本地副本和外部(原始)对象之间没有连接)。编译器也允许省略副本,这意味着当源是右值时,使用原始对象本身。
不要复制函数参数。相反,按值和 让编译器进行复制。- cpp.next.com
“按值”和“按引用”在语义上存在差异。我们从引用传递中获得的“优化”更像是一个结果,而不是一个目标,一个从我们在程序中表达的逻辑和含义派生出来的结果。
另外,考虑到即使在这个范围内引用是 ,我们仍然有一个引用(对另一个独立的对象)。意味着这个对象仍然可以被一些外部(在我们的范围内)力修改。const
最后,我们应该首先努力使语言表达的清晰度,而不是寻求过早的优化。
评论
0赞
Mako
6/30/2021
我认为对于一些void funcA(const std::string&myString),我们想要表达的逻辑和含义是:输入参数是一个常量,函数应该/不能改变它。添加的“&”只是对性能的优化。当一个引用真的“仍然可以被一些外部(在我们的范围内)力量修改”时,我想这会损害原来的含义。但是,我无法找出一些外部来源修改变量的真实示例。有人可以举个例子吗?
0赞
rawrex
6/30/2021
@Mako 如果有多个执行线程对同一对象进行操作(我的意思是受保护和有效的使用,想象一下由两个线程共享的锁)。是的,如果不需要引用,则有助于避免复制,但它的本质不是优化技术。稍后会进行优化。
0赞
Mako
6/30/2021
在下面的评论中,我最初的问题 IgorTandetnik 给出了以下示例: godbolt.org/z/9T5xx1367 .您的线程示例也有帮助。现在,我看到可以在函数之外更改引用的情况,该函数将其作为常量。而且我一直认为使用通过常量引用传递是危险的......它有助于避免复制,但它可能会破坏我们想要为函数参数表达的真正含义(常量)。我不认为谁想在可能更改时指定“const”。谁能启发我?
评论
funcA