是否存在某种功能,指针取消引用会产生右值?
所以,通常的指针给出一个左值:
Foo *p = ...;
fn(p[42]); // p[42] is an lvalue
我希望p[42]
返回一个左值,因此可以为fn(Foo &&)
调用fn(p[42])
:
<some_pointer_type> p = ...;
fn(p[42]); // I'd like to have p[42] be an rvalue, so an fn(Foo &&) would be called
注意:我希望p
具有此功能,指针类型应具有此信息,解除引用它应该给出右值。
答案 0 :(得分:2)
通过fn(std::move(p[42]));
,您可以执行无条件转换为 rvalue 。
move
名称Ptr
在这里实际上是误导性的:没有任何东西被移动,但正在进行演员表。
然后考虑编写一个指针模板*
,其操作符[]
和#include <utility>
class Foo {};
template<typename T>
class Ptr {
public:
Ptr(T* ptr): ptr_{ptr} {}
T&& operator*() { return std::move(*ptr_); }
T&& operator[](int idx) { return std::move(*(ptr_ + idx)); }
private:
T* ptr_;
};
void fn(Foo&& x) { return; }
void fn(const Foo& x) { return; }
int main()
{
Foo foo[50];
Ptr<Foo> p{&foo[0]};
// call void fn(Foo&&)
fn(p[42]);
}
被重载以返回右值:
{{1}}
答案 1 :(得分:0)
指针解除引用的结果类型,即某些重载运算符的类型结果,不能依赖于运行时存储在指针对象中的某些信息,因为它的签名是在编译时定义的。但是可以根据指针原点重载运算符:
#include <string>
#include <iostream>
#include <cstddef>
template<typename TItems>
class t_FancyPointer;
template<typename TItems>
class t_FancyPointer<TItems[]>
{
private: TItems * m_p_items;
public: explicit
t_FancyPointer(TItems * p_items) : m_p_items{p_items} {}
public: TItems &
operator [](::std::size_t const index) &
{
return(m_p_items[index]);
}
public: TItems &&
operator [](::std::size_t const index) &&
{
return(::std::move(m_p_items[index]));
}
};
void
fn(::std::string &&)
{
::std::cout << "rvalue reference" << ::std::endl;
}
void
fn(::std::string &)
{
::std::cout << "lvalue reference" << ::std::endl;
}
::std::string items[4];
t_FancyPointer<::std::string[]> perma_storage{items};
t_FancyPointer<::std::string[]> &
Get_PermaStorage(void)
{
return(perma_storage);
}
t_FancyPointer<::std::string[]>
Get_TempStorage(void)
{
return(t_FancyPointer<::std::string[]>{items});
}
int main()
{
// calls fn(::std::string &)
fn(Get_PermaStorage()[42]);
// calls fn(::std::string &&)
fn(Get_TempStorage()[42]);
return 0;
}
输出:
lvalue reference
rvalue reference
如果您只是想要总是返回&amp;&amp;然后你可以定义一个运算符[]返回一个右值引用:
public: TItems &&
operator [](::std::size_t const index)
{
return(::std::move(m_p_items[index]));
}
虽然我不知道为什么你会这样做。