【问题标题】:Can I delete function for an rvalue version of object?我可以删除对象的右值版本的函数吗?
【发布时间】:2019-12-24 20:58:27
【问题描述】:

由于遗留原因,我正在处理的代码中大量使用了const char*。我试图限制这一点,并偶然发现了一些我想知道的东西。我有类似的东西:

class AClass {
  public:
    const char* getValue() { return _value.c_str(); }
  private:
    std::string _value;
}

但是这个类现在可以通过复制返回,例如。按功能:

AClass getAClass();

我们也可能想把它传递给这样的东西:

void functionFromOtherLibrary(const char* value);

现在想想,这可能会导致错误:

functionFromOtherLibrary(getAClass().getValue());

因为中间有资格在那个时候被销毁。即使上面没有问题,因为它是一个语句,这可能不会:

const char* str = getAClass().getValue();
functionFromOtherLibrary(str);

所以我想写这样的东西:

class AClass {
  public:
    const char* getValue() { return _value.c_str(); }
    const char* getValue() && = delete;
}

禁止在右值上调用该方法。只是尝试一下就给了我:

error C2560: cannot overload a member function with ref-qualifier with a member function without ref-qualifier

我不确定这是不是:

  1. 是有效的构造并且
  2. 是必要的。我见过很多返回 const char*s 的代码,它似乎总是依赖于返回值的对象仍然存在并持有源 std::string 的事实。

如果代码使用 std::strings 保存字符串但只与 C 字符串通信,我将非常感谢更详细的解释。

如果你想建议删除 C 字符串 - 这就是我现在正在尝试做的事情。不过我还是想要一个答案。

【问题讨论】:

  • 执行const char* getValue() && = delete; 会阻止您执行functionFromOtherLibrary(getAClass().getValue());,这可能是一个完全有效的用例。你确定要这样做吗?
  • @NathanOliver 我不能 100% 确定它确实有效。我必须承认,在深入挖掘之后,我对一切都变得不像以前那么确定了。这也是我寻求帮助的原因。
  • 假设你有一些像print(const char * str) { std::cout << str }这样的函数。执行print(getAClass().getValue()); 就可以了,因为对于print 的整个调用,临时文件仍然有效。现在,如果print 要存储指针以供以后使用,那么这将是一个问题,因为它将是一个悬空指针。在这里你必须决定你是限制性的,只是说不允许临时工所以你不会有 UB,或者更难得到它,或者你只是陈述你的合同,如果用户忽略它,这是他们的问题。我属于后者。

标签: c++ c++17 c-strings stdstring rvalue


【解决方案1】:

你不能用没有引用限定符的函数重载带有引用限定符的函数。 MSVC 错误文本在这一点上很好而且很清楚。

但是您可以将 ref-qualifier 添加到另一个:

class AClass {
  public:
    const char* getValue() & { return _value.c_str(); }
    const char* getValue() && = delete;
};

这是否是正确的设计是一个单独的问题 - 但如果您确定它是正确的,这就是您要这样做的方式。

【讨论】:

  • 那么,其他函数一定是ref吧?这有什么影响吗? ref、rvalue 和 value 重载都存在吗?
  • @TomášZato "你不能用没有引用限定符的函数重载带有引用限定符的函数。"
  • 好吧,我承认这是一个愚蠢的问题。我真正想知道的是 ref 重载是否将始终充当原始不合格的。我还希望在此处了解有关此用法正确性的更多详细信息。
  • @TomášZato 原文接受左值和右值,只要它们不是 const。这个版本有两个独立的重载,一个只接受左值,另一个只接受右值。
猜你喜欢
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多