在c ++的上下文中。
我想知道它之间的区别是什么:
T f(T const val);
和此:
T f(T const & val);
我知道一个是值传递,但是,从编译器的角度来看,这是一个不会改变的值,所以我的问题是:
答案 0 :(得分:1)
假设如下:
launch_service(const Configuration); // launches service in a different thread
Configuration config;
launch_service(config);
config.set("key", "value");
如果引用Configuration
,则在单独的线程中运行的服务可能会读取后面添加的配置设置key
。如果按值获取(如示例中所示),则无法反映其他线程以后所做的更改。
这意味着,取一些const value
或const ref
是不同的,编译器必须在前者中创建一个副本。
答案 1 :(得分:1)
示例1:
T f(T const val);
如果编译器无法内联(或以其他方式修改函数f
),则必须复制T
并将其传递给f
。 const
与调用代码的视角没有区别,只在函数f
内部。
示例2:
T f(T const & val);
编译器将val
的地址传递给函数,因此不需要复制。
但是,使用小/简单类型的引用会导致额外的开销,因为参数作为元素的地址传递,f
的内容必须进行额外的操作才能加载地址然后加载val
的实际内容。因此,问题是“复制T
有多复杂,f
使用val
”确定最有效的函数有多复杂。总是,如果您想要获得更好的性能,请测量结果!
最后,如果编译器能够内联代码,它可能会消除对象的所有副本(假设构造函数已知并且不会阻止被删除 - 例如,将I / O添加到构造函数将阻止它被淘汰了)。
答案 2 :(得分:0)
关于
“在
const
值参数传递的情况下,编译器是否仍需要复制?
是的,程序必须表现为,好像一样。
在实践中,可以传递一个地址,然后该函数可以自己制作一个副本,如果有必要的话(因为调用了其他函数)。
请注意,正式参数的顶级const
将被忽略为函数类型;它只影响函数的实现,如果它存在于实现的函数头中。
“哪一个更适合编译器的优化器以及为什么?
在很大程度上取决于机器代码内联的类型,该值是否将存储在调用后可访问的某个位置,以及是否使用整个程序优化。简而言之,这取决于。作为一般规则,如果您认为可能存在效率问题,则衡量。