fre*_*low 72 c++ const rvalue-reference c++11
我猜不是,但我想证实一下.是否有用const Foo&&,Foo哪种类型?
How*_*ant 69
它们偶尔会有用.草案C++ 0x本身在几个地方使用它们,例如:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
Run Code Online (Sandbox Code Playgroud)
上面的两个重载确保了另一个ref(T&)和cref(const T&)函数不绑定到rvalues(否则可能).
更新
我刚刚检查了官方标准N3290,遗憾的是它不公开,它有20.8个Function对象[function.objects]/p2:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
Run Code Online (Sandbox Code Playgroud)
然后我检查了最新的C++ 11后草案,它是公开的,N3485,以及20.8函数对象[function.objects]/p2,它仍然说:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
Run Code Online (Sandbox Code Playgroud)
Ami*_*rsh 12
获取const 右值引用(而不是 for =delete)的语义是说:
恕我直言,以下用例可能是对 const 右值引用的一个很好的用例,尽管语言决定不采用这种方法(请参阅原始 SO 帖子)。
通常建议使用make_uniqueand make_shared,但是unique_ptrandshared_ptr都可以从原始指针构造。两个构造函数都按值获取指针并复制它。两者都允许(即从某种意义上说:不阻止)在构造函数中传递给它们的原始指针的继续使用。
以下代码编译并产生double free:
int* ptr = new int(9);
std::unique_ptr<int> p { ptr };
// we forgot that ptr is already being managed
delete ptr;
Run Code Online (Sandbox Code Playgroud)
双方unique_ptr并shared_ptr能防止上述,如果他们的相关构造期望得到原始指针作为一个const右值,例如用于unique_ptr:
unique_ptr(T* const&& p) : ptr{p} {}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,上面的double free代码不会编译,但以下代码会:
std::unique_ptr<int> p1 { std::move(ptr) }; // more verbose: user moves ownership
std::unique_ptr<int> p2 { new int(7) }; // ok, rvalue
Run Code Online (Sandbox Code Playgroud)
请注意,ptr移动后仍然可以使用,因此潜在的错误并没有完全消失。但是如果用户被要求调用std::move这样的 bug 就会落入常见的规则:不要使用被移动的资源。
有人会问:好的,但为什么是T* const&& p?
原因很简单,允许unique_ptr 从 const 指针创建。请记住,const 右值引用比仅右值引用更通用,因为它同时接受const和non-const。所以我们可以允许以下内容:
int* const ptr = new int(9);
auto p = std::unique_ptr<int> { std::move(ptr) };
Run Code Online (Sandbox Code Playgroud)
如果我们只期望rvalue 引用(编译错误:无法将const rvalue绑定到rvalue),这将不会发生。
无论如何,现在提出这样的事情已经太晚了。但是这个想法确实提出了对 const的右值引用的合理用法。
它们是允许的,甚至函数排名基于const,但由于您无法从引用的 const 对象移动const Foo&&,因此它们没有用。
除了std::ref,标准库也出于同样的目的在std::as_const 中使用 const 右值引用。
template <class T>
void as_const(const T&&) = delete;
Run Code Online (Sandbox Code Playgroud)
获取包装值时,它还用作std::optional 中的返回值:
constexpr const T&& operator*() const&&;
constexpr const T&& value() const &&;
Run Code Online (Sandbox Code Playgroud)
以及在std::get 中:
template <class T, class... Types>
constexpr const T&& get(const std::variant<Types...>&& v);
template< class T, class... Types >
constexpr const T&& get(const tuple<Types...>&& t) noexcept;
Run Code Online (Sandbox Code Playgroud)
这大概是为了在访问包装值时维护值类别以及包装器的常量性。
这对于是否可以在包装的对象上调用 const rvalue 引用限定的函数有所不同。也就是说,我不知道 const rvalue ref 限定函数的任何用途。
| 归档时间: |
|
| 查看次数: |
9033 次 |
| 最近记录: |