将字符串文本传递给需要字符串的函数

Passing string literal to function which expect string

本文关键字:字符串 函数 文本      更新时间:2023-10-16

让我们假设我有一个函数,它期望参数是一个字符串(non const)。但正如我们所知,字符串文字本质上是常量。有什么方法可以将字符串文字传递给期望非常量的函数。 我知道这会导致错误,因为文字本质上是常量,但函数期望非常量。任何转换该函数的方法都可以工作。 听说有const_cast.我可以使用它吗?

void str(string &s); // my function which is expecting a non const string
// main . i want to do something like this 
str("Blah"); // error
void str(string s) // it works fine ? why ?

当你的函数被声明为

void str(string &s);

它只能使用可以转换为string&的表达式来调用。

如果您尝试使用 调用该函数

str("Blah");

它不起作用,因为字符串文字"Blah"无法转换为std::string&。编译器能够从字符串文本构造的临时std::string对象可以转换为std::string const&std::string,但不能转换为std::string&

您在更新的问题中提出的内容(传递对非常量std::string对象的引用)不会(或至少不应该)起作用。

编译器可以从字符串文本创建临时字符串对象,这是绝对正确的。此临时对象可以按值传递。还可以将对 const 字符串对象的引用绑定到临时字符串对象(更一般地说,将对 const T 的引用绑定到临时 T)。

但是,对非 const 类型的引用不能绑定到临时对象,因此编译器将(或至少应该)拒绝您的代码。

但有一个例外:Microsoft 的旧编译器确实允许非 const 引用绑定到临时对象。正如Microsoft的一些人所指出的那样,这是相当无害的 - 它允许你修改临时对象,这通常是相当无用的(当函数返回时对象将被简单地销毁,所以没有其他任何东西可以/永远不会看到修改,就像你通常期望在修改通过非常量引用传递的东西时发生的那样。另一方面,他们认为,由于没有其他人可以看到修改,允许它们是相当无害的。我倾向于不同意后者,因为允许几乎可以肯定是偶然发生的事情是有害的,不是因为程序之后发生了什么,而仅仅是因为编译器没有警告程序员做了一些几乎肯定是错误的事情。

我不确定Microsoft何时在他们的编译器中修复了这个缺点,但最新版本(至少自 VS 2015 以来)拒绝了应有的代码。我知道他们曾经接受过它,但我不确定它更改时的确切版本。

总结

尝试将非 const 引用绑定到临时引用的代码应该被拒绝,但对于 Microsoft 的编译器,它不一定会被拒绝。

不能将临时传递给接受非常量引用的函数。临时死亡,你有一个悬而未决的引用,如果它甚至编译的话。

但是,如果使用 const 引用,则临时的生存期将延长到函数结束。

这绝对没问题。 std::string 有一个看起来像这样的 ctor:

string(const char* text);

所以对str("Blah")的调用将创建一个临时字符串对象(通过调用上面的 ctor),然后调用 str 方法。