L值引用抽象类和`decltype`

She*_*ohn 3 c++ abstract-class decltype c++11

我提出了下面这段代码,认为它不起作用,但令我惊讶的是它的工作绝对正常,我想要一些解释.

#include <cstdio>
#include <algorithm>

struct Abstract
{
    Abstract()
        { printf("\tConstructing Abstract instance.\n"); }

    virtual const char* name() const =0;
    auto talk() const -> decltype(*this)
    {
        printf("My name is %s.\n",name());
        return *this;
    }
};

struct Concrete
    : public Abstract
{
    Concrete() 
        { printf("\tConstructing Concrete instance.\n"); }
    const char* name() const
        { return "Bond"; }
};

int main()
{
    Concrete C;
    printf("James %s.\n",C.talk().name());
}
Run Code Online (Sandbox Code Playgroud)

此代码的输出是:

    Constructing Abstract instance.
    Constructing Concrete instance.
My name is Bond.
James Bond.
Run Code Online (Sandbox Code Playgroud)

Q1 (这是非特异性的,以C++ 11,只是删除decltype和替换auto通过const Abstract&).为什么编译器接受语法C.talk().name()

除非我弄错了,我认为表达式C.talk()可能是一个prvalue(Abstract的副本,不是因为只有一个构造函数输出的情况)或一个左值引用,在这种情况下我不确定是什么因为一个左值引用抽象课对我来说似乎也不可能.

Q2这引出了我的第二个问题:decltype"知道"如何返回某种参考,而不是一个简单的价值?

cel*_*chk 8

Q1:不仅允许对抽象类进行左值引用,而且实际上多态性必不可少.请注意,引用类型对应于表达式的静态类型,而不是对象的动态类型,当然它不能是抽象类(实际上,这也不完全正确,但它足够接近于此目的)回答).

C.talk().name()因此,语法被接受,因为类型Abstract包含成员函数的声明name(),并且它将被正确执行,因为在执行时,实际调用的函数取决于动态类型,Concrete并且具有实现name().

Q2: *this是左值表达式,decltype对于左值表达式,给出左值引用.