【问题标题】:What guarantees that the overloaded non-const method is invoked?什么保证调用重载的非常量方法?
【发布时间】:2013-04-25 20:47:11
【问题描述】:

给定这两个修改和返回字符串的函数:

// modify the original string, and for convenience return a reference to it
std::string &modify( std::string &str )
{
    // ...do something here to modify the string...
    return str;
}

// make a copy of the string before modifying it
std::string modify( const std::string &str )
{
    std::string s( str );
    return modify( s ); // could this not call the "const" version again?
}

此代码适用于我使用 GCC g++,但我不明白为什么/如何。我担心第二个函数会调用自己,让我失去控制的递归,直到堆栈耗尽。这能保证有效吗?

【问题讨论】:

  • 这很可能是尾递归。我不确定将 const-ref 调用转换为循环的语义,因此不要发布答案,而是查找尾递归,您会发现更多信息。
  • @peachykeen:不,这根本不是递归。
  • 考虑选择一个更能突出问题的标题 - 例如“什么保证调用重载的非常量方法?”

标签: c++ recursion signature


【解决方案1】:

你有两个重载函数:

std::string &modify( std::string &str )
std::string modify( const std::string &str )

您传递的是非 const 限定的 std::string。因此,采用非 const 限定参数的函数更合适。如果不存在,编译器可以将非 const 限定字符串转换为 const 限定字符串以进行调用,但对于函数重载,不需要转换的调用比需要转换的调用。

【讨论】:

    【解决方案2】:
    return modify( s ); // could this not call the "const" version again?
    

    没有。它是不是递归。它将调用参数为std::string &other 重载。

    这是因为表达式s的类型是std::string &,它与另一个重载函数的参数类型匹配。

    为了递归,调用点的参数需要转换为std::string const &。但在您的情况下,这种转换是不必要的,因为存在不需要转换的重载。

    【讨论】:

      【解决方案3】:

      这不是递归,而是重载。当您调用第二个函数时,进入它的参数是一个常量字符串。在该函数内部,您调用另一个采用非常量字符串的函数。您正在做的是剥离字符串的 const-ness,而更好的方法是使用 const_cast。

      I'll just link to this other stackoverflow thread.

      【讨论】:

      • 我不想删除 constness。这将导致一个看似 const 的字符串被修改!
      • 您可以通过以下方式分配非常量字符串:std::string &str2 = const_cast<:string>(str)。 str 将保持不变,但您可以随意修改 str2。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      • 2015-08-08
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多