重载函数既不按值也不按引用获取对象,而是获取指向对象的取消引用指针

Overloaded functions neither take objects by value, nor by reference, but take de-referenced pointer to object

预先说明:问题涉及我自己实现的一个vector-class,与std::vector无关

考虑以下运算符重载:

//in the Vector-class(declaration)
friend Vector operator+(const Vector& a, const Vector& b);

//outside the Vector-class(implementation)
Vector operator+(const Vector& a, const Vector&b) {
//...
}

引用两个向量,returns它们的和。 现在,当我尝试以下操作时:

Vector foo();
Vector bar();

Vector byVal = foo + bar; //using objects
Vector byRef = &foo + &bar; //using address

在这两种情况下,我的 IDE 告诉我以下内容:

expression must have integral or unscoped enum-type

在第二种情况下这是有道理的,因为我只会在被调用函数采用指针时传递一个 yield 指针,对于采用引用的函数,我可以传递对象本身,但我不不明白为什么 在这里不能只使用对象。

让我更困惑的是,以下 似乎是可能的:

Vector* foo = new Vector();
Vector* bar = new Vector();

Vector foobar = *foo + *bar;

也就是说,我可以将 取消引用的指针 与重载运算符一起使用。

这种行为的原因是什么,在这种情况下我应该如何使用我的重载运算符?

Vector foo();
Vector bar();

这些不是变量声明。这些是函数声明。它们是 return Vector 并采用空参数列表的函数。

鉴于不能将函数相加,也不能将函数指针相加,foo + bar&foo + &bar都是ill-formed。

为了value-initialise一个变量,你可以使用以下任一方法:

Vector foo{};        // uniform initialsation
auto bar = Vector(); // copy initialisation syntax

I wanted to call the constructor of Vector, that doesn't take any arguments

确实如此。没有参数的函数声明和带有空初始化列表的变量声明是不明确的。这是由一条语言规则解决的,该规则规定如果一段代码在语法上可以是函数声明或其他东西,那么它就是一个函数声明。

如果函数将参数标记为 &,则作为参数传递的对象将通过引用传递。对象的地址是隐式,所以你不必(实际上不能)在要传递的参数对象之前写一个&

进一步注意 Vector foo(); 声明了一个函数,而不是一个对象。这就是为什么您的编译器会抱怨您的两个调用。

Vector operator+(const Vector& a, const Vector&b) {
//...
}

Vector foo;
Vector bar;

Vector byVal = foo + bar; //by reference because parameter in operator + is marked as "call by reference" 
// Wrong: Vector byRef = &foo + &bar;