对象或其重载运算符可以知道它是否正在调用 const 成员函数吗?

Can an object or its overloaded operator know if it's calling a const member function?

提问人:iammilind 提问时间:8/2/2023 最后编辑:Jan Schultkeiammilind 更新时间:9/25/2023 访问量:95

问:

struct X 
{ 
  void foo () {}
  void const_foo () const {}
};
struct Y
{
  X x;
  int i;

  X* operator-> () { return &x; } 
  const X* operator-> () const { return &x; }
};

int main ()
{
  Y y;
  y->foo(); // invokes `Y::operator->`
  y->const_foo();  // invokes `Y::operator->`; BUT I want `Y::operator-> const`!!
}

正如代码中的演示一样,如果用于调用方法,我希望调用该版本。constoperator->const_foo()

我的目的是自动化这一点。因此,下面不是解决方案,我正在寻找:

const_cast<const Y&>(y)->const_foo(); // Don't want this explicit casting

有什么办法可以做到这一点吗?

使用 s 或更改其对象的主体或更改其对象的声明(例如)是可以的。只是,我不想在代码中的方法调用位置使用显式强制转换。templateX, YY y


目的:以上是一个非常简单的例子。如果选择了,那么我在其中调用了一些额外的代码/方法。对于任何被调用的方法,例如 ,最好调用要调用的此额外代码。operator->() constconstXX::const_foo()Y::operator->() const

C++ 模板 C++17 运算符重载 函数限定符

评论

0赞 463035818_is_not_an_ai 8/2/2023
它有什么区别? 无论哪种方式const_foo ()const
0赞 iammilind 8/2/2023
@463035818_is_not_an_ai,上面是一个最小的例子。实际上,如果它被调用,我想做一些特别的事情。operator-> const
0赞 463035818_is_not_an_ai 8/2/2023
恕我直言,添加将使示例更加清晰。std::cout << "this is a side effect"
0赞 Jarod42 8/2/2023
重命名为显式名称?operator->
3赞 n. m. could be an AI 8/2/2023
如果你做的事情与 不同,那么你在这里就有问题了。这就像运行一些自定义代码。别这样。operator-> () constoperator-> ()const_cast

答:

0赞 Mestkon 8/2/2023 #1

正如@Mat所评论的,没有办法仅根据返回类型隐式选择正确的重载。您必须以某种方式告诉编译器在调用站点使用哪个函数,方法是在 const 或非 const 对象上调用它,或者使用单独的函数。

如果要强制使用给定函数来访问 const/non-const 函数,则可能需要将其分为两种不同的返回类型

// Different return types with different interface for const/non-const overloads
struct X {
    void foo();
};
struct ConstX {
    void const_foo() const;
};

struct Y {
    X* operator->();
    const ConstX* operator->() const;
};

您可能还希望完全不要重载,并为 const/non-const 访问使用不同的名称以避免const_cast

struct X {
    void foo();
    void const_foo();
};

struct Y {
    X& x();
    const X& cx();
};

第二个示例也可以与第一个示例结合使用,以强制使用给定的访问函数进行 const/non-const 访问。