C++ pass-by-non-const-reference 方法在 pass-by-const-reference 方法中

Posted

技术标签:

【中文标题】C++ pass-by-non-const-reference 方法在 pass-by-const-reference 方法中【英文标题】:C++ pass-by-non-const-reference method inside pass-by-const-reference method 【发布时间】:2013-04-21 07:46:54 【问题描述】:

我有这个函数pass_by_const(const std::string& s) 想要调用pass_by_non_const(std::string& s)

如果我有这个方法的定义

pass_by_const(const std::string& s)

    pass_by_non_const(s);

编译器会对我产生影响吗?有解决方法吗?我怕pass_by_non_const在我背后修改s。

【问题讨论】:

如果你的编译器允许这样做而没有任何警告,我会得到一个新的编译器。 VC++ 允许将临时变量作为非常量引用传递,但即便如此,也会以适当的(在我看来是强制性的)警告级别进行警告。 确实如此。我只是想找到解决办法。这只是要求更多澄清的便捷方式。 【参考方案1】:

发生了什么

pass_by_const(const std::string& s)

    pass_by_non_const(s);

是:pass_by_const有const参数std::string s,所以不允许修改在封闭范围内定义并作为参数传递给他的字符串s。但是,pass_by_non_const 允许修改 s。这会在编译时引发编译器错误。

但是,可以将 s 的本地非常量副本传递给 pass_by_non_const。然后,可以在pass_by_non_const 的范围内修改本地副本,而作为参数传递给pass_by_const 的封闭范围的s 不会改变。

方法的正确写法是then

pass_by_const(const std::string& s)

    std::string local_copy = s;
    pass_by_non_const(local_copy );

没有更多的编译时错误,local_copy 可以在大多数内部范围内修改,而封闭范围内的 s 不会,遵守 pass_by_const 方法的 pass-by-const-ref-ness。

【讨论】:

【参考方案2】:

您甚至不应该想要pass_by_const 调用pass_by_non_const,因为如果一个参数是一个常量引用,那么您“承诺”不会修改它。

如果你想违反类型系统(这是一件坏事),你可以做一些丑陋的事情,比如

 pass_by_const(const std::string& s)
 
    pass_by_non_const(const_cast<std::string&>(s));
 

但关键是这样做是错误的,可能是undefined behavior。所以任何不好的事情都可能发生(崩溃,甚至程序不小心做了你想做的事)。

如果您想遵守类型系统并避免违反不变量,请按照antitrust's answer 中的建议进行本地复制。当然,制作本地副本可能会很昂贵。

【讨论】:

我在工作中没有违反 const 的正确性,并且我仍然确保 pass_by_const 没有通过 const ref argment 进行修改。 @antitrust "我没有违反 const 正确性" - 你这样做了。 否:每个人都尊重它的承诺,永远不允许通过 const ref 方法传递,并且能够修改参数,即使调用非 const 方法传递也是如此。 好吧,如果非 const 版本不修改任何内容,只需将代码移动到 const 版本,并让非 const 版本调用 const 版本。为什么这么难? 如果一个函数没有修改任何东西,它应该被声明为const

以上是关于C++ pass-by-non-const-reference 方法在 pass-by-const-reference 方法中的主要内容,如果未能解决你的问题,请参考以下文章

C++之父的C++元宇宙

[C++]C++入门到入土篇 HelloWorld 解析 && C++入门

怎么找C++函数需要的头文件?(C++头文件C++函数文档C++文档)

如何识别项目是托管 c++ 项目还是非托管 c++ 项目

C++ 程序员应该使用哪些 C++ 习语? [关闭]

十类C++标准库 十类C++标准库简介