【发布时间】:2016-10-26 01:12:34
【问题描述】:
我确实理解,一般而言,值传递和引用传递存在显着差异,尤其是对于非平凡类型,主要是对象是否被复制,当我们有右值时有一些警告。
但是,我想知道当传递的参数是常量时,编译器是否真的认识到这两个东西在某种程度上是相同的,并自动优化按值传递以通过引用传递?如果不是,我认为几乎总是通过引用传递参数是标准的,对吧?
【问题讨论】:
标签: c++ reference parameter-passing
我确实理解,一般而言,值传递和引用传递存在显着差异,尤其是对于非平凡类型,主要是对象是否被复制,当我们有右值时有一些警告。
但是,我想知道当传递的参数是常量时,编译器是否真的认识到这两个东西在某种程度上是相同的,并自动优化按值传递以通过引用传递?如果不是,我认为几乎总是通过引用传递参数是标准的,对吧?
【问题讨论】:
标签: c++ reference parameter-passing
不,通常编译器不能用传递引用替换传递值,因为在一般情况下可能会引入别名问题。
然后参数的值可以在const 下改变,可以这么说:
void foo( string const a, string& backarai )
{
backarai = "Hm! ";
backarai += a;
}
void bar( string const& a, string& backarai )
{
backarai = "Hm! ";
backarai += a;
}
auto main() -> int
{
string s = "Well well well!";
foo( s, s ); // Sets s to "Hm! Well well well!"
string t = "Well well well!";
bar( t, t ); // Sets t to "Hm! Hm!"
}
但是,如果在特定情况下编译器可以证明这样的别名不会成为问题,并且复制字符串没有副作用等等,即如果它可以证明两种情况下可观察到的程序行为是相同的,那么它可以这样优化。这就是“好像”规则在起作用。它允许任何优化,其中唯一可观察到的变化是代码的运行时间。
【讨论】:
std::string是编译器厂商提供的,所以很有可能,但不知道有没有搞定。