如果函数返回引用,则使自动成为引用
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]
中,它对不同类型的值进行了重要区分,可以是 lvalues、xvalues 和 prvalues 。在您的情况下 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
我需要以下代码才能工作:
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:
Theauto
anddecltype(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]
中,它对不同类型的值进行了重要区分,可以是 lvalues、xvalues 和 prvalues 。在您的情况下 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