提问人:Niall 提问时间:7/18/2014 最后编辑:Niall 更新时间:6/19/2016 访问量:11656
ref-qualifier 'const &&' 有什么用?
What is use of the ref-qualifier `const &&`?
问:
在上一个问题之后,我一直在挖掘 ref-qualifiers。
给定下面的代码示例;
#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();
}
输出如您所料:
get() & get() const &
get() &
get() const &&
这使用 clang 和 gcc 4.9.1(虽然不是 4.9.0)编译和运行。现场样本在这里。
在常规代码中(示例用于查看代码的编译和运行方式)。
- 方法上的 ref-qualifier 的目的是什么?
const &&
该方法无法修改对象上的内容(它是),尝试从该方法实际上根本不会移动。据推测,您希望能够修改对象,因为它是一个 r 值,并且不会存在很长时间。如果要删除限定方法,则代码将绑定到限定方法,这是有道理的。const
return std::move(abc);
const &&
std::string
const &&
std::move(a3).method()
const &
- 如果有的话,限定为的方法和限定为的方法之间隐含的语义差异是什么?即实现会有什么变化,或者你为什么想要两者?
const &
const &&
- 真的能够被“移”出临时对象吗?
std::string
- 在这种情况下,“规范”签名会是什么样子?
std::string get() const &&
答:
我看到了引用限定方法的两个主要用途。一种是您在方法中显示的那样,您可以使用它来选择可能更有效的实现,该实现仅在您知道该对象将不再使用时才可用。但另一个是安全提示,以防止在临时对象上调用某些方法。get() &&
您可以像在这种情况下一样使用符号,尽管实际上我会保留这种方法来修改方法,尤其是那些可能成本高昂的方法。在不检索某些东西的情况下进行突变然后丢弃对象没有多大意义,如果执行突变的成本很高,则加倍意义。此构造为编译器提供了一种标记和防止此类使用的方法。get() const && = delete
评论
=delete
const&&
我们可以在文章中找到对这个问题的类似探索 const rvalue references 有什么用? 一个突出的用途是标准库中的这个示例:
template <class T> void ref (const T&&) = delete;
template <class T> void cref (const T&&) = delete;
这将完全禁用 和 for 右值。我们可以在 C++11 标准草案的函数对象第 2 段中找到这些声明。ref
cref
20.8
Scott Meyers在C++11的通用引用中提到了这种用法:
即使简单地添加一个 const 限定符也足以禁用 将“&&”解释为通用引用:
评论
const T&&
template <class T> void ref (const T&)
const T&&
关于 const&&&...
(一般情况)
限定符对成员方法的有用性充其量是最小的。不能以与方法允许修改对象相同的方式修改对象;毕竟是这样(如前所述,确实改变了这一点)。因此,我们将无法撕掉它的内脏,因为临时的无论如何都会到期,就像我们在类似于正常情况下一样.const&&
&&
const
mutable
move
在许多方面,最好在类型对象的有用性开始的上下文中评估 的有用性。const T&&
函数参数有多大用处?正如此处(针对此问题)的另一个答案所指出的,它们在声明已删除的函数时非常有用,例如在本例中const&&
const T&&
template <class T> void ref (const T&&) = delete;
显式禁止 PRVeValue 和 Xvalue 值类别类型的对象与函数一起使用,并绑定到所有 PRVeValue 和 Xvalue 对象。const T&&
方法限定符有什么用?
const&&
有趣的是,在提案中,C++ 库扩展 § 5.3 包括重载,例如optional
constexpr T value() const &&;
被限定为并指定执行与替代项相同的操作。const&&
&&
对于这种情况,我可以推断出的原因;这是为了完整性和正确性。如果在右值上调用该方法,则无论它是否存在,它都会执行相同的操作。遗嘱需要由被移动的包含对象或使用它的客户端代码来处理。如果包含对象的某个状态,则可以合法地更改该状态。value()
const
const
mutable
这很可能还是有一些优点的;排名不分先后...
- 要声明它
= delete
以禁止该方法对 prvalues 和 xvalues 使用。 - 如果类型具有可变状态,并且限定符在目标环境中有意义(可能除了其他限定符之外),请考虑它。
- 如果要实现泛型容器类型,则为了完整性和正确性,请考虑添加它并执行与方法相同的操作。这里的建议是从标准库(及其扩展)中排序。
&&
对于合格方法,“规范”签名会是什么样子?
const&&
由于该方法将执行与该方法相同的操作,因此我主张签名与签名匹配。&&
&&
评论
const
const &
const
optional
&&
const&&
假设我们有一个带有状态的类型。然后既允许我们突变该状态,又表明这种突变是安全的。mutable
const&&
struct bar;
struct foo {
mutable std::vector<char> state;
operator bar() const&;
operator bar() const&&;
};
const
不是绝对的。
除非可变状态,否则为了提取状态而丢弃方法并不安全,因为以这种方式从实际对象中提取状态是未定义的行为。const
const&&
const
评论
mutable
带来了一些非常有趣的东西,因为它在 C++11 中也说明了线程安全。
std
std
评论