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

Make auto become a reference if reference is returned by function

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

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是从initilizer值中减去的:

Declarations [dcl.spec.auto]/1: The auto and decltype(auto) type-specifiers are used to designate a placeholder type that will be replaced later by deduction from an initializer.

Initializers [dcl.init]/1: A declarator can specify an initial value for the identifier being declared.

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

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] 中,它对不同类型的值进行了重要区分,可以是 lvaluesxvaluesprvalues 。在您的情况下 getChild() 评估为左值,该左值是您引用的对象而不是它的某个临时副本。

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

[dcl.ref]/2: A reference type that is declared using & is called an lvalue reference, (...)

但是您需要通过说明您的 auto 应该是一个参考来明确地做到这一点:

auto &child = getChild();

编辑: 有关自动工作方式的更多信息:Herb Sutter's GotW blog