Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ ref限定词const&;有什么用&;`?_C++_C++11_Language Lawyer_Move Semantics_Rvalue Reference - Fatal编程技术网

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
在这种情况下,虽然实际上我会保留这种方法来修改方法,尤其是那些可能代价高昂的方法。在不检索对象的情况下对对象进行变异然后丢弃对象是没有多大意义的,如果执行变异的代价很高,则更是如此。这种构造为编译器提供了一个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在以下文章中提到了这种用法:

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


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

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

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

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

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

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

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


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

假设我们有一个具有
可变
状态的类型。那么
常量&&
将允许我们对该状态进行变异,并表明这种变异是安全的

struct bar;

struct foo {
  mutable std::vector<char> state;
  operator bar() const&;
  operator bar() const&&;
};
结构条;
结构foo{
可变std::向量状态;
运算符bar()常量&;
运算符bar()常量&&;
};
const
不是绝对值


除非是可变状态,否则在
const&
方法中丢弃
const
以提取状态是不安全的,因为以这种方式从实际
const
对象提取状态是未定义的行为。

我想我同意这篇文章,一般来说,特别是对于ref限定的方法,它几乎没有什么用处呃,我不想禁止它被使用。注意,在那篇文章之前,有多个相关的问题。例如,@BenVoigt有几个,我没有超出我的第一次搜索命中,因为它很好地回答了这个问题,实际上它以一种非常类似的方式巧妙地探讨了这个问题。尽管这个问题到目前为止还没有解决质量最好的.Ref限定符从来都不表示通用引用。我不知道这个答案与这个问题有什么关系。你的答案不是很清楚。
const t&
真的只取r值吗?为什么不只实现
template void Ref(const t&)
?在这种情况下,尝试传递r值将失败。如果您所写的是真的,那么使用
常量T&&
是愚蠢的
=delete
可以让您对对象的使用方式有很大的控制权,我认为这将是
常量&&
的一般用途(如果有的话).
mutable
给这个表带来了一些非常有趣的东西,因为它还说明了C++11中的线程安全问题。@niall仅在
std
容器中使用。或者由
std
提供的类型中使用。这是一个很好的观点。我同意,从技术上说是的。不过,从个人角度来看,我通常会体验
struct bar;

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