c++中交换两个引用的一种方法
A way to swap two references in C++
交换两个引用确实是一个坏主意。引用不应该是可重置的,所以它不应该是可能的。我就知道这么多。
我想做的是交换两个引用,就像交换两个指针一样:地址被交换但不是数据。假设:
int a = 0, b = 1;
int *pA = &a, *pB = &b;
std::swap(pA, pB);
现在*pA为1,*pB为0,但a仍然为0,b仍然为1。然而,对于引用,这是不可能的:
int a = 0, b = 1;
int &rA = a, &rB = b;
std::swap(pA, pB);
现在引用被交换了,但是原始值也被交换了。我唯一能想到的是:
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++是否会接受它(但我想象它应该)。
整个引用交换应该用在一个对象中,这个对象是用对另一个对象的引用构造的,我想在它们上面做一个swap()函数。我希望避免使用指针,因为引用具有很好的非零特性。这也是一个更好的设计(除了resetable_ref本身)。
有没有人有更好的办法?有人能想到一些兼容性/未定义的行为问题,可能会遇到这个?
我写的大部分代码没有编译,如果你注意到一些拼写错误,请原谅我。
EDIT:在我看来,很多人都没有抓住问题的关键。我知道如何使用指针,甚至知道如何在一个漂亮的模板中包装指针。问题被标记为"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); }
}
请注意,没有默认的ctor,初始化的ctor接受一个引用,这使得这个类不可为空。
唯一的问题是,要访问最终的T成员,作为"。"操作符,不可重写,您需要其他东西来实现此目的。
最简单的就是使用*和->作为…
T* operator->() const { return p; }
T& operator*() const { return *p; }
在mutable_ref
声明中定义-
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 有没有一种方法可以在编译时获得作用域类名
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 有没有一种方法可以捕获进程中的堆栈溢出?C++Linux
- 我想直接在结构中插入,但没有一种方法可以正确避免填充问题
- 类中一种方法的部分专用化
- 只需要知道我在c ++中打印模式的方式是否有效,或者有另一种方法可以有效地做到这一点
- 有没有一种方法可以忽略Qt c++中的文件名大小写敏感性?
- 有没有一种方法可以使用图形在C++中逐个字母地打印控制台中的文本
- 有没有一种方法可以将数据从javascript发送到exe文件
- 有没有一种方法可以从函数中返回一个新对象或对现有对象的引用
- 在C++中,有没有一种方法可以让我在不传递参数的情况下拥有一个函数
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 有没有一种方法可以使用typedef中的参数名称
- C++中有没有一种方法可以通过指定列表中的每个成员变量来构造对象