为什么对字符串参数的 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
阅读隐式转换了解更多信息。
为什么对字符串参数的 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
阅读隐式转换了解更多信息。