2013-05-01 41 views
8

鉴于这些2个函数修改,并返回一个字符串:使用GCC G ++什么保证重载的非const方法被调用?

// 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? 
} 

此代码对我的作品,但我不明白为什么/如何。我担心第二个函数会自动调用,让我失控递归,直到堆栈耗尽。这是保证工作吗?

+0

这是最有可能的尾递归。我不确定将const-ref调用转换为循环的语义,因此不会发布答案,而是查看尾递归,并且可以找到更多信息。 – ssube 2013-05-01 19:42:21

+2

@peachykeen:不,它根本不是递归的。 – 2013-05-01 19:44:14

+0

考虑选择一个更好地关注问题的标题 - 例如“什么保证重载的非const方法被调用?” – user2246674 2013-05-01 19:48:20

回答

9

你有两个重载函数:

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

什么你传递一个非const限定std::string。因此,采用非常量限定参数的函数更适合。如果不存在,编译器可能会将非const限定字符串转换为const限定字符串以进行调用,但对于函数重载不需要转换的调用而言,要比需要调用转换。

3
return modify(s); // could this not call the "const" version again? 

号是递归。它会调用其他过载参数为std::string &

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

为了缓解,呼叫站点的参数需要转换为std::string const &。但在你的情况下,这种转换是不必要的,因为存在不需要转换的过载。

1

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

I'll just link to this other stackoverflow thread.

+0

我不想删除常量。这将导致一个看起来常量字符串被修改! – 2013-05-01 19:55:22

+0

你可以做的是通过做一些事情来分配非常量字符串:std :: string&str2 = const_cast (str)。 str将保持不变,但您可以根据需要修改str2。 – Shaz 2013-05-01 20:04:48

相关问题