如果函数返回引用,则使auto成为引用



我需要以下代码才能工作:

class Parent{
public:
virtual void fun(){throw 0};
};
class Child:public Parent{
public:
virtual void fun(){/*Success*/};
};
Parent& getChild(){
return *(new Child());
}
void main(){
auto child=getChild();
child.fun();    
}

但由于某种原因,auto创建了Parent而不是Parent &,这将正确地使用派生方法。有没有办法强制auto创建引用,而不是使用简单的实例?

C++标准解释了auto是从initializer值中扣除的:

声明[dcl.spec.auto]/1:autodecltype(auto)类型说明符用于指定占位符类型后来被初始化项的推导所取代

Initializers[dcl.init]/1:声明符可以指定初始值值

因此,当您编写以下声明符时:

int t = f(10); 
auto x = y; 
auto child = getChild(); 

右侧被求值为生成值的表达式。这个值用于初始化左侧声明的变量。

值不是引用。它不像指针和地址。在表达式求值中,无论何时使用引用,都会考虑引用的值。您可以通过以下简单片段看到这一点:

int x=15;
int&y = x; 
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl; 

因此,在您的情况下,表达式值是Parent,而不是Parent &。这就是为什么您的auto将被推断为具有Parent类型。

然而,C++标准并没有以相同的方式考虑所有的值。在[basic.lval]中,它对不同类型的值进行了重要的区分,这些值可以是lvalues

xvaluesrvalues当你有这样一个左值时,你可以创建一个对它的引用:

[dcl.ref]/2:使用&声明的引用类型称为左值参考,(…(

但你需要明确地说,你的汽车应该是一个参考:

auto &child = getChild();

编辑:关于汽车工作方式的更多信息:Herb Sutter的GotW博客

最新更新