【问题标题】:How to disallow temporaries in functions taking const references?如何在采用 const 引用的函数中禁止临时变量?
【发布时间】:2023-03-27 22:26:01
【问题描述】:

背景:

假设我有这样的事情:

struct item
{
    int x;
    item(int y): x(y) {}
}

class item_view
{
    const item& it;
public:
    item_view(const item& it_) : it(it_) {}

    friend std::ostream& operator<<(std::ostream& os, const item_view& view)
    {return os;} //actually is more complicated
}

我之所以不能只重载operator&lt;&lt;,是因为它更人性化,并且视图是用来将数据传递给SQL的,所以必须对记号和其他一些字符进行转义。

问题:

有人可能想做这样的事情:

auto view = item_view(2);
std::cout << view;

这似乎是未定义的行为。

问题:

如何防止临时构建item_view

【问题讨论】:

  • 显然?这里没有 UB... 由2 构造的临时对象一直存在到语句结束。
  • @Quentin,请注意。我相信人们使用它就像auto view = item_view(2); std::cout &lt;&lt; view;那当然应该是UB。
  • 是的,那个时候是:)
  • 顺便说一句,构造函数参数名称不需要与要初始化的数据成员名称不同。你可以使用item(int x): x(x) {}item_view(const item&amp; it) : it(it) {}就好了。

标签: c++ c++14 temporary


【解决方案1】:

您可以提供一个更适合临时对象的附加重载,然后将其删除。例如:

#include <string>

void foo(const std::string &) {}
void foo(std::string &&) = delete;

int main()
{
    std::string world = "World";
    foo("Hello");   // Doesn't compile, wants to use foo(std::string &&)
    foo(world);     // Compiles
}

【讨论】:

  • 哇,这比我想象的要简单。谢谢。
  • 另外,item 的 ctor 应该是明确的。
  • @Snps,在实际代码中它是一些用户定义的类型。我的代码库周围没有太多模板,所以我相信应该没问题。
  • 这对于转换构造函数可能不是一个好主意。可以改用LWG 2993's PR 中显示的技术。
  • 无论如何,您都希望在此处使用const std::string&amp;&amp; 以正确拒绝 const 右值。
猜你喜欢
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 2010-10-20
  • 2017-07-17
相关资源
最近更新 更多