the*_*ine 5 c++ pointers reference
这确实是交换两个引用的一个坏主意。这些引用不应重设,因此不可能。我知道的那么多。
我想要做的,就是交换两个引用,在某种程度上人们会交换两个指针:地址被交换,但没有数据。假设:
int a = 0, b = 1;
int *pA = &a, *pB = &b;
std::swap(pA, pB);
Run Code Online (Sandbox Code Playgroud)
现在* pA为1,* pB为0,但是a仍然为0,b仍然为1。但是,对于引用,这是不可能的:
int a = 0, b = 1;
int &rA = a, &rB = b;
std::swap(pA, pB);
Run Code Online (Sandbox Code Playgroud)
现在,引用被交换了,但是原始值也被交换了。我唯一能想到的是:
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);
Run Code Online (Sandbox Code Playgroud)
现在,a仍然为0,b仍然为1,并且交换了rrA和rrB内部的引用。可惜的是,如果没有相当丑陋的运算符=(),它将无法正常工作。至少它在MSVC中对我有用,不确定g ++是否会接受它(但我想应该)。
整个引用交换应该在一个对象中使用,该对象是对内部另一个对象的引用而构造的,我想对它们进行swap()函数。我想避免使用指针,因为引用具有很好的非空性功能。这也是一个更好的设计(resetable_ref本身除外)。
有谁对它的执行有更好的主意吗?谁能想到与此相关的一些兼容性/未定义的行为问题?
我编写的大多数代码都是未经编译的,如果发现一些错字,请多多包涵。
编辑:在我看来,很多人都缺少问题的重点。我知道如何使用指针,甚至如何将指针包装在一个不错的模板中。这个问题被标记为“ hack ”,这是所期望的。不要告诉我“不要这样做,请使用指针”之类的东西,因为那不是我要的。如果您不喜欢该主题,请不要回答,但不要因为要使用指针而对这个问题投反对票。
可变引用...只不过是一个指针,为此您需要像引用一样隐式取消引用。
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); }
}
Run Code Online (Sandbox Code Playgroud)
请注意,缺少默认构造函数,并且初始化构造函数采用引用,这使得此类不可为空。
唯一的问题是,要访问最终的 T 成员,需要使用“.”。运算符,不可重写,您需要其他东西来达到此目的。
简单的事情就是使用 * 和 -> as...
T* operator->() const { return p; }
T& operator*() const { return *p; }
Run Code Online (Sandbox Code Playgroud)
mutable_ref
在声明内定义 -