C++:将字符串文字作为字符串传递并导致编译失败,为什么

C++: Pass string literal as a string& leads to compilation failure, why

本文关键字:字符串 编译 失败 为什么 文字 C++      更新时间:2023-10-16

我使用g++4.1.2来编译这个:

    cat 1.cpp
#include<iostream> 
#include<string> 
using namespace std; 
void f(const string& s){} 
void g(string& s){} 
void h(string s){} 
int main() 
{ 
    string s="abc"; 
    f("abc"); 
    g("abc”);//Error 
    h("abc"); 
    return 0; 
} 

在" g(); "行失败

$ g++ 1.cpp 
1.cpp: In function ‘int main()’: 
    1.cpp:11: error: invalid initialization of non-const reference of type ‘std::string&’ from a    temporary of type ‘const char*’ 
1.cpp:5: error: in passing argument 1 of ‘void g(std::string&)’ 

我不太明白,只要" abc "可以是std::string:

的构造函数参数

f(),"abc"可用于构造string(const char*),作为对string

的const引用。

对于h(), " abc "可用于构造一个值为r的临时std::string对象。

对于g(),为什么不能用它来构造左值引用string&是好吗?

这是因为语言规则是这样设计的。可以将右值绑定到const左值引用(并将其生命周期延长到引用的生命周期),因为这是明确允许的。

假设c++ 03,因为你使用的是c++ 4.1.2

§8.5.3 [dcl.init. init][参考文献]/5

对类型"cv1T1"的引用由type的表达式初始化"cv2T2"如下:

  • 如果初始化表达式
    • 是左值(但不是位域),"cv1T1"与"cv2T2"或
    • 是引用兼容的。
    • 有一个类类型(即T2is一个类类型),并且可以隐式地转换为类型为[…]的左值
  • 否则,引用必须指向非易失性const类型[…]
    • 如果初始化表达式是一个右值,具有t2a类类型,并且"cv1T1"与"cv2T2"是引用兼容的,[…]
    • 否则,使用非引用规则从初始化表达式创建并初始化类型为"cv1T1"的临时对象拷贝初始化(8.5)。然后将引用绑定到暂时的。