const string &s 和 string &s 有什么区别?
What is the difference between const string &s and string &s?
这是来自 c++ primer:
的代码
string::size_type findChar(const string &s, char c, string::size_type & occurs){
auto ret = s.size();
occurs = 0;
for (decltype(ret) i = 0; i != s.size(); ++i){
if (s[i] == c){
if (ret == s.size())
ret = i;
occurs++;
}
}
return ret;
}
int main () {
string::size_type ctr;
cout << findChar("hello, world!", 'o', ctr);
}
从 const string &s
中删除 const
后发生错误。
error: cannot bind non-const lvalue reference of type 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string&'} to an rvalue of type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string'}
cout << findChar("hello, world!", 'o', ctr);
我想知道,在这种情况下,const
关键字会改变编译器的哪些行为?谢谢你帮助我。
std::string 是一个 class。 const char* 是指向内存的指针,希望包含以空字符结尾的字符串。您可以使用 std::string 按值传递并进行复制,而无需调用 strcpy 等函数。
尽可能使用 std::string,当需要指向字符串的指针时使用 c_str() 方法,例如,对于较旧的 C 库。
像 "hello, world!"
这样的字符串文字不是 std::string
。所以要调用你的函数,编译器必须为你创建一个 std::string
。这样的对象称为临时。因此,在第一种情况下,编译器使用 "hello, world!"
创建一个 std::string
,然后 绑定 该临时字符串以引用参数 s
.
但是 C++ 有一条规则,您不能将临时对象绑定到非常量引用。但是,当您将 s
从 const std::string&
更改为 std::string&
时,您是在要求编译器执行此操作。这就是错误消息告诉您的内容。
如果您将代码更改为此
string::size_type ctr;
string hello = "hello, world!";
cout << findChar(hello, 'o', ctr);
现在即使没有 const 也能编译。这里的区别是编译器不再创建临时 std::string
(因为 hello
已经是 std::string
)。因此关于临时引用和非常量引用的规则不适用。
在调用代码中,s
传递的对象是"hello, world!"
,是一个字符串,其内容不可更改。在函数 findChar
中,类型 const string &s
是对类型 const string
对象的名为 s
的引用。这两个类型匹配,所以编译成功。
但是,参数 string &s
表示对 string
类型对象的命名 s
的引用 - 这是一个可变(可变)字符串。但是传入的参数("hello, world!"
)是一个不能改变的字符串。发生这种情况时,编译器会指示类型不匹配错误。
这是来自 c++ primer:
的代码string::size_type findChar(const string &s, char c, string::size_type & occurs){
auto ret = s.size();
occurs = 0;
for (decltype(ret) i = 0; i != s.size(); ++i){
if (s[i] == c){
if (ret == s.size())
ret = i;
occurs++;
}
}
return ret;
}
int main () {
string::size_type ctr;
cout << findChar("hello, world!", 'o', ctr);
}
从 const string &s
中删除 const
后发生错误。
error: cannot bind non-const lvalue reference of type 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string&'} to an rvalue of type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string'} cout << findChar("hello, world!", 'o', ctr);
我想知道,在这种情况下,const
关键字会改变编译器的哪些行为?谢谢你帮助我。
std::string 是一个 class。 const char* 是指向内存的指针,希望包含以空字符结尾的字符串。您可以使用 std::string 按值传递并进行复制,而无需调用 strcpy 等函数。
尽可能使用 std::string,当需要指向字符串的指针时使用 c_str() 方法,例如,对于较旧的 C 库。
像 "hello, world!"
这样的字符串文字不是 std::string
。所以要调用你的函数,编译器必须为你创建一个 std::string
。这样的对象称为临时。因此,在第一种情况下,编译器使用 "hello, world!"
创建一个 std::string
,然后 绑定 该临时字符串以引用参数 s
.
但是 C++ 有一条规则,您不能将临时对象绑定到非常量引用。但是,当您将 s
从 const std::string&
更改为 std::string&
时,您是在要求编译器执行此操作。这就是错误消息告诉您的内容。
如果您将代码更改为此
string::size_type ctr;
string hello = "hello, world!";
cout << findChar(hello, 'o', ctr);
现在即使没有 const 也能编译。这里的区别是编译器不再创建临时 std::string
(因为 hello
已经是 std::string
)。因此关于临时引用和非常量引用的规则不适用。
在调用代码中,s
传递的对象是"hello, world!"
,是一个字符串,其内容不可更改。在函数 findChar
中,类型 const string &s
是对类型 const string
对象的名为 s
的引用。这两个类型匹配,所以编译成功。
但是,参数 string &s
表示对 string
类型对象的命名 s
的引用 - 这是一个可变(可变)字符串。但是传入的参数("hello, world!"
)是一个不能改变的字符串。发生这种情况时,编译器会指示类型不匹配错误。