显然,如果你重载->
->*
它不会自动工作,并且必须手动重载。
为什么标准容器的迭代器除了->
之外,不会重载->*
,强制使用(*iter).*mem_ptr
而不是iter->*mem_ptr
?
#include <iostream>
#include <vector>
struct S
{
int x;
};
int main()
{
std::vector<S> vec = {{42}};
auto mem_ptr = &S::x;
std::cout << (*vec.begin()).*mem_ptr << 'n'; // This line compiles.
std::cout << vec.begin()->*mem_ptr << 'n'; // This line doesn't compile.
}
需要注意的是,这些问题通常无法回答,以下是operator->*()
可能不会过载的几个原因。虽然有可能真正的答案是没有人想到它。如果这对您来说是一个重要的缺失语言功能,您可以随时提交提案。
对于初学者来说,ptr->*pmd
通常不是一个非常常用的表达方式。因此,你不能写it->*pmd
的事实并不是大多数人错过的,尤其是当(*it).*pmd
以 2 个额外字符为代价实现完全相同的目标时。这里的潜在上行空间似乎相当小。尽管如此,迭代器应该与指针一致,所以这是有意义的。但。。。
指向成员的指针不仅仅是指向成员数据的指针,我们还可以具有指向成员函数的指针,并且可以编写(ptr->*pmf)()
,其中ptr->*pmf
本身的格式不正确。你根本无法用operator->*
获得这些语义 - 要使调用操作正常工作,ptr->*pmf
基本上必须返回一个 lambda。所以现在,这实际上变得相当复杂 - 除非你想只支持ptr->*pmd
.使用任何方法,您都与指针不一致。
对于输入迭代器,您根本不希望支持operator->*()
,因为它会产生一个立即悬而未决的引用。
就我个人而言,成本(弄清楚如何指定这些运算符,为哪些迭代器以及如何处理指向成员函数的指针)似乎并不值得(在很少编写的表达式中保存 2 个字符)。