类似指针的类和 ->* 运算符

Pointer-like classes and the ->* operator

本文关键字:gt 运算符 指针      更新时间:2023-10-16

我最近遇到需要将指向成员的指针应用到迭代器指定的对象。我尝试过自然语法:

ite->*ptr = 42;

令我沮丧的是,它没有编译。迭代器不会重载operator->*,但更令人惊讶的是,智能指针也不会重载。我需要求助于以下笨拙的手段:

(*ite).*ptr = 42;

实验(见下面的实际例子(表明,至少从C++14开始,对于自定义类,对于指向成员的指针和指向成员函数的指针,这样的语法似乎是可以实现的。

因此:

  • 标准的类指针类不重载operator->*是有原因的,还是只是疏忽
  • 在定义自己的类似指针的类时,我应该重载operator->*吗?还是同样的原因也适用于我

实例——什么编译,什么不编译,以及自定义类的概念验证。

您可以用一个自由函数重载->*。它不一定是成员。

template <typename P,
          typename T,
          typename M>
M& operator->* (P smartptr, M T::*ptrmem)
{
    return (*smartptr).*ptrmem;
}

现在,所有定义了一元operator*的东西(迭代器、智能指针等等(也可以使用->*。您可能希望以一种更可控的方式进行,即分别为已知迭代器、已知智能指针等定义它。

由于显而易见的原因,这将不适用于成员功能。对于这种情况,需要专门化/重载并返回绑定的std::function

template <typename P,
          typename T,
          typename M,
          typename ... Arg>
std::function<M(Arg&&...)> 
operator->* (P smartptr, M (T::*ptrmem)(Arg... args))
{
    return [smartptr,ptrmem](Arg&&... args) -> M 
      { return ((*smartptr).*ptrmem)(std::forward<Arg>(args)...); };
}

这就是((&*ite)->*ptr) = 42;想要做的吗?