一种在C ++中交换两个引用的方法 [英] A way to swap two references in C++

查看:190
本文介绍了一种在C ++中交换两个引用的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这真的是一个错误的想法,交换两个引用。引用不应该是可重置的,所以它不应该是可能的。

this is really about a bad idea of swapping two references. The references are not supposed to be resetable so it is not supposed to be possible. That much i know.

我想做的是交换两个引用,一种方式是交换两个指针:地址交换

What i want to do, is to swap two references, in a way one would swap two pointers: the addresses are swapped but not the data. Assume:

int a = 0, b = 1;
int *pA = &a, *pB = &b;
std::swap(pA, pB);

现在* pA为1,* pB为0,但a仍为0,b仍为1 。这是不可能的,参考:

Now *pA is 1 and *pB is 0, but a is still 0 and b is still 1. This is, however, impossible with references:

int a = 0, b = 1;
int &rA = a, &rB = b;
std::swap(pA, pB);

现在引用被交换,但原始值也被交换。我唯一能想到的是这样:

Now the references are swapped, but the original values are swapped as well. The only thing i can think of is this:

template <class _Ty>
struct resetable_ref {
    _Ty &ref;

    inline resetable_ref(resetable_ref &r)
        :ref(r.ref)
    {}

    inline resetable_ref(_Ty &_ref)
        :ref(_ref)
    {}

    inline resetable_ref &operator =(resetable_ref &r)
    {
        if(sizeof(resetable_ref) == sizeof(void*)) // compile-time constant (true)
            *reinterpret_cast<void**>(this) = *reinterpret_cast<void**>(&r);
        else
            memcpy(this, &r, sizeof(resetable_ref)); // optimized away as dead code
        return *this;
    }

    inline operator _Ty &()
    {
        return ref;
    }
};

int a = 0, b = 1;
resetable_ref<int> rrA(a), rrB(b);
std::swap(rrA, rrB);

现在a仍为0,b仍为1,rrA和rrB中的引用被交换。可惜它不工作没有相当丑陋的操作符=()。至少它对我来说在MSVC,不知道g ++会接受它(但我想象它应该)。

Now a is still 0 and b is still 1, and the references inside rrA and rrB are swapped. Pity that it doesn't work without the rather ugly operator =(). At least it works for me in MSVC, not sure if g++ will accept it (but i imagine it should).

整个参考交换应该用于对象,它是通过引用另一个对象构造的,我想对它们做一个swap()函数。我想避免使用指针,因为参考的好的非零性特征。它也将是一个更好的设计(除了resetable_ref本身)。

The whole reference swap is supposed to be used in an object which is constructed with a reference to another object inside, and i'd like to make a swap() function on them. I'd like to avoid using pointers because of the nice non-nullarity feature of the references. It would also be a nicer design (except for the resetable_ref itself).

有人有更好的想法如何去吗?任何人都可以想到一些兼容性/未定义的行为问题,可能会遇到这个?

Does anyone has a better idea of how to go about it? Can anyone think of some compatibility / undefined behavior issues one could run into with this?

我编写了大部分代码而不编译,如果你注意到一些错字。

I wrote most of the code without compiling, please bear with me if you notice some typo.

编辑:在我看来,很多人都缺少问题的要点。我知道如何使用指针,或者甚至如何包装指针在一个漂亮的模板。问题标记为 hack ,这是预期的。不要告诉我的东西,像不要做,使用指针,因为这不是我问的。

EDIT: It seems to me that a lot of people is missing the point of the question. I know how to use pointers, or even how to wrap pointers in a nice template. The question is tagged "hack" and that is what is expected. Don't tell me stuff like "don't do it, use pointer" since that is not what i asked. If you don't like the topic, don't answer, but don't downvote the question just because you would use pointer.

推荐答案

如果你不喜欢这个主题,不要回答,

一个可变的引用是...不再是一个指针,你需要隐式取消引用,像引用have。

A mutable reference is ... no more tha a pointer, for which you need implicit dereferencing like reference have.

template<class T>
class mutable_ref
{
public:
    mutable_ref(T& t) :p(&t)
    {}

    operator T&() { return *p; }
    operator const T&() const { return *p; }

    void swap(mutable_ref& s)
    { std::swap(p,s.p); }

private:
    T* p;
};

// just in case you also want to specialize std::swap for mutable_ref.
// not necessary, since the generic std::swap<T> use twice =, that is available.
namespace std
{
    template<class T>
    void swap(mutable_ref<T>& a, mutable_ref<T>& b)
    { a.swap(b); }
}

注意缺少一个默认的ctor, ,这使得这个类不可为null。

Note the absence of a default ctor, with an initializing ctor taking a reference, that makes this class not-nullable.

唯一的问题是,要访问最终的T成员,是。

The only problem is that, to access eventual T members, being the "." operator, not overridable, you need something elese for that purpose.

简单的事情是使用*和 - > as ...

The simple thing is use * and -> as...

T* operator->() const { return p; }
T& operator*() const { return *p; }

定义在 mutable_ref

这篇关于一种在C ++中交换两个引用的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆