为代理 类 覆盖 std::swap c++
Override std::swap for Proxy classes c++
我被指派用自定义随机访问迭代器实现 vector<bool>
class,将每个 bool
表示为 unsigned int
数组中的一个位。我正在使用代理 class,它有一个指向 unsigned int
的指针和一个 index
变量,说明正在修改哪个位。
所以我的 vector<bool>
s operator[]
看起来像:
BoolVectorProxy operator[](std::size_t index) {
validate_bounds(index);
return BoolVectorProxy(&array[index / BLOCK_CAPACITY], index % BLOCK_CAPACITY);
}
到目前为止一切顺利 - 然而当我们需要时会发生什么,在迭代器上(也 returns BoolVectorProxy
在括号运算符和解引用运算符上),做一些交换?
此代码无法编译:
Vector<bool> a({true, false});
std::swap(a[0], a[1]);
std::cout << a[0] << " " << a[1] << std::endl;
它应该打印 0 1
显然但是不太愉快的错误消息说我无法从 rvalue
初始化类型 BoolVectorProxy&
的非常量引用输入 BoolVectorProxy
。该错误是可以理解的 - 它尝试使用默认值 std::swap
但无法将我返回的 rvalue
转换为引用。
如何解决这个问题?
问题是 std::swap
声明为:
template< class T >
void swap( T& a, T& b );
对于不是 MSVC 的编译器,您不能将右值传递给它,而 a[0]
是右值(a[1]
也是)。您也不能为 BoolVectorProxy
提供自己的 std::swap
专业化,因为那个 still 必须采用左值引用。
唯一的解决方案是在关联的命名空间中编写您自己的 swap
,以便可以通过参数相关查找找到它:
namespace N // or whatever
{
struct BoolVectorProxy { ... };
// take proxies by value
void swap(BoolVectorProxy a, BoolVectorProxy b)
{
// something like this
bool tmp = static_cast<bool>(a);
a = static_cast<bool>(b);
b = tmp;
}
}
并不合格调用swap
:
Vector<bool> a({true, false});
using std::swap;
swap(a[0], a[1]);
这是一个非常普遍的需求,将其包装在:
template <typename T>
void adl_swap(T&& a, T&& b) {
using std::swap;
swap(std::forward<T>(a), std::forward<T>(b));
}
你可以用它来写:
Vector<bool> a({true, false});
adl_swap(a[0], a[1]);
我被指派用自定义随机访问迭代器实现 vector<bool>
class,将每个 bool
表示为 unsigned int
数组中的一个位。我正在使用代理 class,它有一个指向 unsigned int
的指针和一个 index
变量,说明正在修改哪个位。
所以我的 vector<bool>
s operator[]
看起来像:
BoolVectorProxy operator[](std::size_t index) {
validate_bounds(index);
return BoolVectorProxy(&array[index / BLOCK_CAPACITY], index % BLOCK_CAPACITY);
}
到目前为止一切顺利 - 然而当我们需要时会发生什么,在迭代器上(也 returns BoolVectorProxy
在括号运算符和解引用运算符上),做一些交换?
此代码无法编译:
Vector<bool> a({true, false});
std::swap(a[0], a[1]);
std::cout << a[0] << " " << a[1] << std::endl;
它应该打印 0 1
显然但是不太愉快的错误消息说我无法从 rvalue
初始化类型 BoolVectorProxy&
的非常量引用输入 BoolVectorProxy
。该错误是可以理解的 - 它尝试使用默认值 std::swap
但无法将我返回的 rvalue
转换为引用。
如何解决这个问题?
问题是 std::swap
声明为:
template< class T >
void swap( T& a, T& b );
对于不是 MSVC 的编译器,您不能将右值传递给它,而 a[0]
是右值(a[1]
也是)。您也不能为 BoolVectorProxy
提供自己的 std::swap
专业化,因为那个 still 必须采用左值引用。
唯一的解决方案是在关联的命名空间中编写您自己的 swap
,以便可以通过参数相关查找找到它:
namespace N // or whatever
{
struct BoolVectorProxy { ... };
// take proxies by value
void swap(BoolVectorProxy a, BoolVectorProxy b)
{
// something like this
bool tmp = static_cast<bool>(a);
a = static_cast<bool>(b);
b = tmp;
}
}
并不合格调用swap
:
Vector<bool> a({true, false});
using std::swap;
swap(a[0], a[1]);
这是一个非常普遍的需求,将其包装在:
template <typename T>
void adl_swap(T&& a, T&& b) {
using std::swap;
swap(std::forward<T>(a), std::forward<T>(b));
}
你可以用它来写:
Vector<bool> a({true, false});
adl_swap(a[0], a[1]);