为什么对字符串参数的 const 引用可以采用字符串文字?

Why can a const reference to a string parameter take string literals?

为什么对字符串参数的 const 引用可以采用字符串文字?字符串文字,如 "hello",不是变量,那么为什么这段代码有效?

class CVector {
    public:
        int x, y;
        CVector() {};
        ~CVector() { delete ptr; }
        string* ptr;
        void doSomething(const string& str) { ptr = new string(str); }
        void print() { cout << "\n" << *ptr; }
};
int main()
{
    result.doSomething("asdas");
    result.print();
    return 0;
}

首先,我认为引用作为参数用于避免复制过程并直接访问作为参数的变量(虽然我仍然是正确的)。但是字符串字面量 "asdas" 不是变量,为什么参数可以以字符串字面量为参数呢?我的意思是因为参数 str 是一个引用,它会成为那个实体的别名,对吧?如果是这样,文字只是变成了一个变量吗?

参数列表不应该包含 string& str 而不是 const 引用,以便在 str 的构造中使用文字吗?

const 引用不会在引用存在时一直保持引用的实体存在吗?如果是这样,你为什么要对文字这样做?

std::string 有一个隐式的 const char * 转换构造函数。

允许编译器进行 一个 隐式转换以使类型匹配,因此它使用所述 ctor 将 const char * 转换为 std::string 临时自从 const&(const 左值引用)被允许绑定到临时对象(并延长它们的生命周期)以来,它从那里开始一帆风顺。

当你这样做时

result.doSomething("asdas");

编译器会查看您是否有 doSomething(const char[]);,但什么也没找到。由于没有合适的函数,它会尝试找到一个重载,该重载采用可以从 const char[] 构造的东西,并找到 doSomething(const string& str)。由于允许编译器进行一个用户定义的转换,它从字符串文字构造一个临时 std::string 并通过引用 const 将该临时传递给函数。

Shouldn't the parameter list consist of string& str instead of the const reference, so that the literal would be used in the construction of str?

不,这仅适用于对 const 的引用,不适用于常规引用,因为常规引用无法绑定到临时对象。

And doesn't a const reference keep the referenced entity alive for as long as the reference is alive? If so, why would you do that to a literal?

仅当对象是函数局部对象时,对const 的引用才会延长对象的生命周期。在函数的范围内,对象将存在,因为调用该函数的表达式尚未结束,但如果您尝试在 class 中保留对 std::string 的引用,那将不起作用。

实际上你的代码被翻译成了

int main()
{
    CVector result
    {
        std::string temp = "asdas";
        result.doSomething(temp);
    }
    result.print();
    return 0;
}

String literals, like "hello", are not variables

术语 "variables" 的定义非常模糊,没有任何具体概念的真正支持。

表达式"hello"表示一个对象,它具有您无法修改的静态存储持续时间。与任何其他表达式一样,它可能被用于初始化其他一些对象。在这种情况下,您正在使用表达式初始化 std::string(在其衰减为 const char*)之后。

您缺少的是 "middle step",从该文字构建临时 std::string,然后通过绑定到 ref-to-[=15= 来延长其生命周期].

所以,是的:

const std::string temp{"Hello world"};   // the compiler creates this transparently
const std::string& ref = temp;  // this is yours, and it extends temp's life

阅读隐式转换了解更多信息。