【问题标题】:Passing string literal to function which expect string将字符串文字传递给期望字符串的函数
【发布时间】:2019-10-23 05:09:07
【问题描述】:

让我们假设我有一个函数,它期望参数是一个字符串(非 const)。但正如我们所知,字符串文字本质上是 const 。有什么方法可以将字符串文字传递给期望非常量的函数。 我知道这会导致错误,因为文字本质上是 const,但函数需要非 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 ?

【问题讨论】:

  • “文字本质上是 const,但函数期待非 const。”。请注意,类型也不同。 const char[5]std::string&。临时 std::string 可以从 "Blah" 创建,但临时不绑定到非 const (lvalue-)reference。

标签: c++ string function constants


【解决方案1】:

当你的函数被声明为

void str(string &s);

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

如果你尝试调用函数

str("Blah");

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

【讨论】:

    【解决方案2】:

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

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

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

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

    我不确定 Microsoft 何时在他们的编译器中修复了这个缺陷,但最近的版本(至少从 VS 2015 开始)按应有的方式拒绝了代码。我知道他们曾经接受过它,但我不确定它更改时的确切版本。

    总结

    尝试将非常量引用绑定到临时对象的代码应被拒绝,但使用 Microsoft 的编译器则不一定如此。

    【讨论】:

    • 听起来很吓人,微软应该有警告没有?
    • @Oblivion 我记得 rsharper++ 会给出警告“将非常量引用绑定到临时是 MSVC 扩展”,但 CL 本身不会。
    【解决方案3】:

    您不能将临时值传递给接受非常量引用的函数。临时死掉了,你有一个悬空的引用,如果它甚至可以编译的话。

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

    【讨论】:

      【解决方案4】:

      绝对没问题。 std::string 的 ctor 看起来像:

      string(const char* text);
      

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

      【讨论】:

      • 你能再看看吗?这次是参考
      猜你喜欢
      • 2022-11-26
      • 1970-01-01
      • 2021-02-24
      • 2016-01-28
      • 2013-12-11
      • 1970-01-01
      • 2014-03-19
      • 2014-09-06
      相关资源
      最近更新 更多