Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译器如何选择正确的函数?_C++_Compiler Construction_Overloading - Fatal编程技术网

C++ 编译器如何选择正确的函数?

C++ 编译器如何选择正确的函数?,c++,compiler-construction,overloading,C++,Compiler Construction,Overloading,我写了一个小的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'

我写了一个小的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版本而不是另一个返回向量的版本?此外,像我这样编写相同函数的更多版本是否是一种好的做法?

返回类型不参与重载解析。换句话说,您不能有只在返回类型上不同的函数


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

如果vector1不是const,它会选择

void Vector::Rotate(const double angle, Vector & axis)
对于成员函数,有一个隐藏参数

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) 
对象向量1的指针是
vector*


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

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


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

我知道。但是const起作用,这就是代码编译的原因。你可以在constness上重载。编译器没有问题,重载是合法的,因为其中一个是
const
方法,而另一个不是。好的做法?不,语义真的很混乱。明确函数的作用。为什么会这样?我认为将方法声明为const可以防止它意外地修改类的成员变量。那么,为什么调用依赖于对象呢?方法上的“const”有点双重含义。1.告诉编译器对象不会更改。2.如果有没有“const”的重载,告诉编译器调用哪个函数。我也感到困惑。如果有人知道为什么会这样,我会感兴趣的。:)@MarcDuQuesne:重载解析规则就是这样处理的,它与其他上下文中的规则完全相同:
void f(int&);void f(const int&);int i;f(i)将调用非常量版本。考虑到另一种选择,非常量版本优先于常量版本。@MarcDuQuesne现在可能是时候回顾一下导致这种混淆的函数的
const
版本不需要存在了。它只调用了2个公共方法。复制(赋值)和非常量旋转。@Sarien成员函数有一个隐式
this
参数,成员函数上的
const
应用于隐式
this
;i、 e.
struct S{void foo()const;}
有点像
struct S{};void foo(S const*此)。因此,就像参数上的限定符一样,
const
参与重载解析和确定
参数的类型?我认为将方法声明为const可以防止它意外地修改类的成员变量。那么,为什么调用依赖于对象?我已经更改了我的答案,希望它能解释它