【问题标题】:How does the compiler choose the right function?编译器如何选择正确的函数?
【发布时间】:2013-03-11 16:59:33
【问题描述】:

我写了一个小的 3d 矢量类。特别是我写了两个函数,一个用于旋转向量,一个用于返回向量本身的旋转副本。所以我有以下内容:

Vector Vector::Rotate(const double angle, Vector& axis) const {
Vector b=*this;
b.Rotate(angle,axis);
return (b);
}

void Vector::Rotate(const double angle, Vector & axis) {

/* let's promote this vector to a quaternion */
Quaternion V (0,*this);

/* quaternion describing the rotation */
Quaternion q (cos(angle/2),axis*sin(angle/2));

/* actual rotation  */
*this = (q*V*q.conjugate()).Vec();
}

现在,当我写这样的东西时:

 vector2 = vector1.Rotate(rbo::M_PUCKER,i);

我得到错误: 没有运算符“=”匹配这些操作数 操作数类型为:Vector = void

我希望编译器能够理解我想要什么:为什么他选择 void 版本而不是另一个返回向量的版本?此外,按照我的方式编写更多版本的相同功能是一种好习惯吗?

【问题讨论】:

  • 好的做法? 没有。语义真的很混乱。明确函数的作用。

标签: c++ compiler-construction overloading


【解决方案1】:

编译器仅根据调用成员函数的对象来选择const 或非const 重载。如果对象(或引用)是const,它将选择const 重载。

这是好的做法吗?不,从你对编译器应该做什么感到困惑这一事实看来很明显。编写易于阅读和解释而不会混淆的代码通常是一种好习惯:)

【讨论】:

  • 为什么会这样?我认为将方法声明为 const 只是防止它意外修改类的成员变量。那么,为什么调用依赖于对象呢?
  • 方法上的“const”有点双重含义。 1.告诉编译器对象不会改变。 2. 如果没有“const”的重载,告诉编译器调用哪个函数。我也觉得这很混乱。如果有人知道为什么会这样,我会很感兴趣。 :)
  • @MarcDuQuesne:这就是重载解析规则的处理方式,与其他上下文完全相同:void f(int&); void f(const int&); int i; f(i); 将调用非常量版本。给定替代方案,非常量版本优先于 const 版本。
  • @MarcDuQuesne 现在可能是审查导致这种混乱的函数的const 版本不需要存在的好时机。它只调用 2 个公共方法。复制(赋值)和非常量旋转。
  • @Sarien 成员函数有一个隐含的this 参数并且成员函数上的const 适用于隐含的this;即struct S { void foo() const; }; 有点像struct S {}; void foo(S const *this);。因此,就像参数上的const 限定符一样,const 参与重载解析和确定this 参数的类型。
【解决方案2】:

返回类型不参与重载决议。换句话说,您不能拥有仅返回类型不同的函数。

我认为您的代码只能编译,因为其中一个函数是“const”。

【讨论】:

  • 我知道。但是 const 有所作为,这就是代码编译的原因。
  • 你可以在 constness 上重载。
  • 编译器没有问题,重载是合法的,因为其中一个是const方法,另一个不是。
【解决方案3】:

如果vector1不是const,它会选择

void Vector::Rotate(const double angle, Vector & axis)

对于成员函数,有一个隐藏参数this,

Vector Vector::Rotate(const double angle, Vector& axis) const 
//actually is 
Vector Rotate(const Vector const * this,const double angle, Vector& axis) const 

void Vector::Rotate(const double angle, Vector & axis) 
//actually is 
void Rotate(Vector const * this,const double angle, Vector& axis) 

你的对象vector1的指针是vector *

我猜编译会选择最匹配的一个

【讨论】:

  • 查看对大卫回答的评论:为什么会这样?我认为将方法声明为 const 只是防止它意外修改类的成员变量。那么,为什么调用依赖于对象呢?
  • 我的答案已经改了,希望能解释一下
猜你喜欢
  • 2015-05-19
  • 1970-01-01
  • 2011-02-11
  • 2013-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 2012-05-27
相关资源
最近更新 更多