![](/img/trans.png)
[英]why copy constructor is called when passing temporary by const reference?
[英]Why is copy constructor called even when parameter is marked 'const'?
考虑以下两个功能:
int foo(const std::string x) {
return x.length();
}
int foo2(const std::string& x2) {
return x2.length();
}
打电话的时候
std::string a("hello world!");
foo(a);
编译器似乎仍然将临时对象(通过复制构造函数创建)传递给foo
( https://godbolt.org/z/p2ID1d )
为什么这样做? x是常量,因此它不会被改变foo
,因此编译器仍然应该能够直接传递a
相同的方式它然后调用foo2(a)
旁注:我正在查看由godbolt生成的函数类型:
foo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
foo2(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
我猜这个答案与const
在foo
的定义中被删除的事实有关,但我不知道为什么。 对不起,如果我错过了一些明显的东西。
谢谢!
对于非引用参数,当编译器存储函数的签名时,实际上会忽略const
。 例如,给定此函数原型:
void func(std::string);
func
可以使用此签名实现:
void func(const std::string) // This is NOT an overload.
{}
因此const
对值参数的传递方式没有任何影响。 他们被复制了。 const
仅影响函数在函数实现中的使用方式。
编译器没有优化它是正确的。 你可以做点什么
#include <iostream>
#include <thread>
void foo(const std::string x) {
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
std::cout << x.length() << '\n';
}
int foo2(const std::string& x2) {
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
std::cout << x2.length() << '\n';
}
int main() {
std::string a("hello world!");
std::thread t1([&]{
foo(a);
});
std::thread t2([&]{
foo2(a);
});
a = "";
t1.join();
t2.join();
return 0;
}
这甚至可能在后台发生,编译器也不会知道。
传递值时,编译器必须创建副本。
传递const
值的效果仅在于您的函数不允许修改它接收的副本。 通过const &
- 这样做没有任何好处,相反,它涉及副本效率较低。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.