C++ ref限定词const&;有什么用&;`?

C++ ref限定词const&;有什么用&;`?,c++,c++11,language-lawyer,move-semantics,rvalue-reference,C++,C++11,Language Lawyer,Move Semantics,Rvalue Reference,在前面的问题之后,我一直在挖掘裁判资格赛 给出下面的代码示例 #include <iostream> #include <string> #include <utility> struct A { std::string abc = "abc"; std::string& get() & { std::cout << "get() &" << std::endl; return abc;

在前面的问题之后,我一直在挖掘裁判资格赛

给出下面的代码示例

#include <iostream>
#include <string>
#include <utility>

struct A {
  std::string abc = "abc";
  std::string& get() & {
    std::cout << "get() &" << std::endl;
    return abc;
  }
  std::string get() && {
    std::cout << "get() &&" << std::endl;
    return std::move(abc);
  }
  std::string const& get() const & {
    std::cout << "get() const &" << std::endl;
    return abc;
  }
  std::string get() const && {
    std::cout << "get() const &&" << std::endl;
    return abc;
  }
};

int main()
{
  A a1;
  a1.get();
  const A a2{};
  a2.get();
  A().get();
  const A a3{};
  std::move(a3).get();
}
#包括
#包括
#包括
结构A{
std::string abc=“abc”;
std::string&get(){

std::cout我看到ref限定方法的两个主要用途。一个类似于您在
get()中显示的&&
方法,您可以使用它来选择一个可能更高效的实现,该实现只有在您知道对象将不再使用时才可用。但另一个是一个安全提示,用于防止对临时对象调用某些方法


您可以使用类似于
get()的符号const&&=delete
在这种情况下,虽然实际上我会保留这种方法来修改方法,尤其是那些可能代价高昂的方法。在不检索对象的情况下对对象进行变异然后丢弃对象是没有多大意义的,如果执行变异的代价很高,则更是如此。这种构造为编译器提供了一个我看到ref限定方法的两个主要用途。一个是您在
get()中显示的&&
方法,您可以使用它来选择一个可能更高效的实现,该实现只有在您知道对象将不再使用时才可用。但另一个是一个安全提示,用于防止对临时对象调用某些方法


您可以使用类似于
get()的符号const&&=delete
在这种情况下,虽然实际上我会保留这种方法来修改方法,尤其是那些可能代价高昂的方法。在不检索对象的情况下对对象进行变异然后丢弃对象是没有多大意义的,如果执行变异的代价很高,则更是如此。这种构造为编译器提供了一个y来标记和防止此类使用。

我们可以在文章中找到类似的问题探讨,其中一个突出的用途是标准库中的示例:

template <class T> void ref (const T&&) = delete;
template <class T> void cref (const T&&) = delete;
模板void ref(const T&&)=删除;
模板void cref(const T&&)=删除;
这将禁用所有右值的
ref
cref
。我们可以在
20.8节
函数对象第2段中找到这些声明

Scott Meyers在以下文章中提到了这种用法:

即使简单地添加常量限定符也足以禁用 将“&&”解释为通用参考:


我们可以在文章中找到对这个问题的类似探索,突出的一个用途是标准库中的示例:

template <class T> void ref (const T&&) = delete;
template <class T> void cref (const T&&) = delete;
模板void ref(const T&&)=删除;
模板void cref(const T&&)=删除;
这将禁用所有右值的
ref
cref
。我们可以在
20.8节
函数对象第2段中找到这些声明

Scott Meyers在以下文章中提到了这种用法:

即使简单地添加常量限定符也足以禁用 将“&&”解释为通用参考:


关于
常量和&
的有用性(一般)

const&
限定符在成员方法上的用处最多是最小的。不能以
&
方法允许修改对象的相同方式修改对象;毕竟它是
const
(如前所述,
mutable
确实改变了这一点)因此,我们将无法挖出它的内脏,因为临时性的东西无论如何都会过期,就像我们在类似于正常的
移动的东西中一样

在许多方面,
const&&
的有用性可以从类型为
const T&&
的对象的有用性开始进行最佳评估。函数参数
const T&&&
的有用性如何?
,如另一个答案(对这个问题)中所指出的,它们在声明函数已删除时非常有用,例如在本例中

template <class T> void ref (const T&&) = delete;
限定为
常量和&
,并指定执行与
和&
备选方案相同的操作

对于这种情况,我可以推断的原因是,这是为了完整性和正确性
方法在一个右值上被调用,然后它执行相同的操作,与它是否为
const
无关。
const
将需要被移动的包含对象或使用它的客户端代码来处理。如果包含的对象存在一些
可变的
状态,则该状态可以合法地我变了

这很可能仍然有一些优点;没有特别的顺序

  • 声明它
    =delete
    以禁止在prvalues和xvalues上使用该方法
  • 如果类型具有<强>可变状态< /强>,并且限定符在目标环境中有意义(可能除了其他限定符),请考虑它。
  • 如果您正在执行泛型容器类型,那么对于<强>完整性和正确性<强>,考虑添加它并执行与<代码> &和/> >方法相同的动作。这里的建议是从标准库(及其扩展)排序的。
const&
限定方法的“规范”签名是什么样的


由于该方法将执行与
&
方法相同的操作,因此我主张签名与
&
签名匹配。

关于
常量和
的有用性(一般)

const&
限定符在成员方法上的用处最多是最小的。不能以
&
方法允许修改对象的相同方式修改对象;毕竟它是
const
(如前所述,
mutable
确实改变了这一点)因此,我们将无法挖出它的内脏,因为临时性的东西无论如何都会过期,就像我们在类似于正常的
移动的东西中一样

在许多方面,t的有用性
struct bar;

struct foo {
  mutable std::vector<char> state;
  operator bar() const&;
  operator bar() const&&;
};