是否有某种功能,指针取消引用给出右值?

时间:2017-12-05 10:21:50

标签: c++

是否存在某种功能,指针取消引用会产生右值?

所以,通常的指针给出一个左值:

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具有此功能,指针类型应具有此信息,解除引用它应该给出右值。

2 个答案:

答案 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]));
}

虽然我不知道为什么你会这样做。