不,我不相信这里还有替代机制。
虽然 ref 限定方法可以在某些情况下提供不同的行为,但重载是根据调用它们的对象的状态来解析的。它们没有解决它们返回的对象的使用问题。
在下面的活生生的例子 http://coliru.stacked-crooked.com/a/3e2ae971d7b15c65,我围绕 a 创建一个包装器std::vector
,在分配到索引时尝试自动增长向量,并在仅从索引读取时允许未定义的行为。
但它不是这样工作的:
template <typename T>
struct AutoVector
{
std::vector<T> m_vec;
AutoVector() { m_vec.resize(1); }
T& operator[](const size_t index) &
{
std::cout << "Inside operator[" << index << "]&\n";
if (m_vec.size() < index)
m_vec.resize(index);
return m_vec[index];
}
T operator[](const size_t index) &&
{
std::cout << "Inside operator[" << index << "]&&\n";
return m_vec[index];
}
};
如果通过以下方式调用,两者都会调用左值限定operator[] &
:
AutoVector<int> avec;
avec[4] = 6;
std::cout << avec[4] << "\n";
--> Inside operator[4]&
--> Inside operator[4]&
--> 6
如果在临时对象上调用它,它可以调用右值限定的operator[] &&
:
std::cout << AutoVector<int>()[0] << "\n";
--> Inside operator[0]&&
--> 0
这不具有所需的行为。对返回的代理对象应用相同类型的测试operator[]
通常会导致它在所有情况下调用右值限定的方法,除非代理被捕获并命名。它仍然无法反映代理的使用方式。