const 引用函数参数:是不是可以禁止临时对象?
Posted
技术标签:
【中文标题】const 引用函数参数:是不是可以禁止临时对象?【英文标题】:const reference function parameter: Is it possible to disallow temporary objects?const 引用函数参数:是否可以禁止临时对象? 【发布时间】:2018-10-17 02:50:44 【问题描述】:可以有一个强制执行以下语义的函数参数:
参数不会被函数改变。 调用函数永远不会为参数创建副本或临时对象。
例子:
void f(const std::string & str);
接口告诉客户端参数不会被改变,如果参数已经是std::string类型,则不会创建副本。
不过还是可以这样称呼
const char * hello = "hello";
f(hello);
在进入函数 f 之前创建一个临时 std::string 对象,并在退出 f 后再次销毁它。
是否可以通过不同的函数声明或(假设)更改 std::string 实现来禁止这种情况。
【问题讨论】:
对我来说听起来像是 XY 问题。该语言的优点之一是自动临时创建和绑定。你为什么要禁止这个?如果您关心由于调用构造函数而可能导致的性能下降,那应该不是 API 提供者的问题,而是调用者的问题。std::string
的实际解决方案是使用 std::string_view
或自制解决方案。
必须查一下 xy-problem 是什么意思。不,我不这么认为。同意这将是客户的责任。但这也是我,我很好奇我是否可以确保我不会在我的电话中犯错误。 std::string 在这里仅用作示例。对 std::string 不是特别感兴趣。一件好事是我学到了一些关于 =delete 的新知识。
【参考方案1】:
我要在这里从头开始。
或通过(假设)更改
std::string
实现
不要这样做,因为害怕鼻恶魔。说真的,不要。让标准库以标准方式运行。
是否可以通过不同的函数声明来禁止这一点
事实上,另一个声明只是门票。添加一个接受右值引用的重载,并将其定义为已删除:
void f(std::string && str) = delete;
重载解析会临时选择它,删除的定义会导致错误。您的预期函数现在只能使用左值调用。
【讨论】:
std::string 只是一个大家都知道的例子,我同意我不想改变它。 delete 关键字很有趣,我必须尝试一下。我只知道以这种方式删除默认构造函数等。 @LudwigSchulze - 您可以为任何函数提供已删除的定义。当您想防止某些事情时,更容易使重载解决方案蓬勃发展:) 我觉得在尝试了这个之后,我可能会对有~5个参数的情况有一个后续问题,其中~3个参数具有这种语义。当然,这将是一个新问题。以上是关于const 引用函数参数:是不是可以禁止临时对象?的主要内容,如果未能解决你的问题,请参考以下文章