通过 const 指针而不是 const 引用传递临时引用;此解决方法格式是否正确?

Passing a temporary by const pointer instead of const reference; is this workaround well-formed?

提问人:dragonroot 提问时间:11/4/2023 最后编辑:Remy Lebeaudragonroot 更新时间:11/4/2023 访问量:126

问:

显然,根据 C++ 标准,不能将 const 指针作为函数的参数传递给临时,而传递 const 引用是完全可以的,即使两者本质上是相同的。

这令人费解,到目前为止,我唯一的解释是 C++ 不能微妙到允许获取临时地址,只要所述地址不比表达式更长。不过,我们可以欺骗它允许这样做。我的问题是,它仍然是一个格式良好的程序吗?

代码如下:

#include <string>
#include <iostream>

std::string const * constRefToPtr( std::string const & v )
{
  return &v;
}

void takeStringPtr( std::string const * s )
{
  std::cout << *s << std::endl;
}

int main()
{
  // This one isn't allowed by the standard
  // takeStringPtr( &std::string( "Hello, world" ) );

  // However, this is just fine, apparently. Is this a well-formed program though?
  takeStringPtr( constRefToPtr( std::string( "Hello, world" ) ) );

  return 0;
}

正如你所看到的,我们引入了一个帮助程序,用于将 const 引用转换为 const 指针。据我所知,由于临时应该一直存在到表达式的末尾,因此这是一个格式良好的程序。我说得对吗?

如果我是,标准库中已经有这样的助手吗?

P.S. 如果您想知道为什么我首先需要它,我有一个函数,它接受 const 指针而不是 const 引用,因为它允许传递 .不过,我仍然希望能够将临时消息传递给它。nullptr

C++ 语言-律师 未定义行为 生存期

评论

0赞 Jarod42 11/4/2023
它的格式很好。在 std 中,std::addressof 是故意删除的。
0赞 dragonroot 11/4/2023
哇。所以他们不允许直接拿地址,而是介绍了一个帮手?为什么?难道他们不能简单地允许前一件事吗?是因为常量吗?好的,我想我现在明白了:)
0赞 BoP 11/4/2023
他们没有。不幸的是,该语言允许重载,因此可能不是...operator&&xx
0赞 Jarod42 11/4/2023
该函数还不允许获取临时地址。
1赞 dragonroot 11/4/2023
嗯,C++就是这样。例如,您可以将 a 存储到临时字符串。你可以的事实并不意味着你应该。string_view

答:

3赞 Jarod42 11/4/2023 #1

这是一个格式良好的程序。我说得对吗?

它确实格式良好。

标准库中已经有这样的助手了吗?

它将是 std::addressof,但临时 (rvalue) 的重载被故意删除(具有与 类似的限制)。&temporary()

评论

0赞 dragonroot 11/4/2023
如果程序格式良好,他们为什么要强迫我做助手?这真是令人费解
0赞 Red.Wave 11/4/2023
它看起来不错,但颠覆了规则。
0赞 dragonroot 11/4/2023
不知道你的意思是什么。如果它的格式很好,那么它的规则就没有意义了,不是吗?
0赞 Jarod42 11/4/2023
这些结构是危险的,拆分行以添加中间变量(以提高可读性)会使程序格式不正确,指针悬空。一些 API 试图尽可能安全。
2赞 Jarod42 11/4/2023
您仍然可以自由创建不安全的功能。我认为尝试限制危险的 API 是件好事。这些危险的结构大多是从历史中继承下来的......