【问题标题】:What is the difference between const string &s and string &s?const string &s 和 string &s 有什么区别?
【发布时间】:2020-12-13 08:06:16
【问题描述】:

这是c++入门的代码:

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 &amp;s 中删除const 后发生错误。

错误:无法将 'std::__cxx11::string&' {aka 'std::__cxx11::basic_string&'} 类型的非常量左值引用绑定到 'std::__cxx11::string' 类型的右值 {又名'std::__cxx11::basic_string'} cout

我想知道,在这种情况下,const 关键字会改变编译器的哪些行为?谢谢你帮助我。

【问题讨论】:

  • 到底发生了什么错误?
  • 删除 const 意味着“这个值可以被操纵”,这可能是不允许的,具体取决于参数的提供方式。
  • @nathanpierson 我已将其添加到问题中。
  • 你需要学习c++移动语义

标签: c++ literals string-literals


【解决方案1】:

"hello, world!" 这样的字符串文字不是std::string。所以要调用你的函数,编译器必须为你创建一个std::string。这样的对象称为临时对象。因此,在第一种情况下,编译器使用"hello, world!" 创建一个std::string,然后绑定该临时字符串以引用参数s

但是,C++ 有一个规则,您不能将临时对象绑定到非常量引用。但是,当您将 sconst std::string&amp; 更改为 std::string&amp; 时,您是在要求编译器这样做。这就是错误消息告诉您的内容。

如果您将代码更改为此

string::size_type ctr;
string hello = "hello, world!";
cout << findChar(hello, 'o', ctr);

现在即使没有 const 也可以编译。这里的区别在于编译器不再创建临时的std::string(因为hello 已经是std::string)。所以关于临时和非常量引用的规则不适用。

【讨论】:

    【解决方案2】:

    std::string 是一个类。 const char* 是一个指向内存的指针,它希望包含一个以 null 结尾的字符串。您可以使用 std::string 按值传递并进行复制,而无需调用 strcpy 之类的函数。

    尽可能使用 std::string,当需要指向字符串的指针时使用 c_str() 方法,例如,对于较旧的 C 库。

    【讨论】:

    • 这一切都是真的,但似乎并没有回答所提出的问题。
    【解决方案3】:

    在调用代码中,为s传递的对象是"hello, world!",它是一个字符串,其内容不能更改。在函数findChar 中,const string &amp;s 类型是一个名为s 的对const string 类型对象的引用。这两种类型匹配,编译成功。

    但是,参数string &amp;s 表示一个名为s 的引用,指向string 类型的对象——这是一个可变(可变)字符串。但是传入的参数 ("hello, world!") 是一个无法更改的字符串。发生这种情况时,编译器会指示类型不匹配错误。

    【讨论】:

    • 这是不真实的。类型不匹配导致编译器构造一个临时对象,并且它是关于将非常量引用绑定到导致编译器错误的临时对象的规则,而不是类型不匹配。
    猜你喜欢
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 2010-12-29
    • 2010-12-14
    相关资源
    最近更新 更多