c++ - 在 C++0X 中评估 auto 的类型

标签 c++ c++11

我正在使用 C++0X 标准中的自动功能,但我对如何做出类型决定感到困惑。考虑以下代码。

struct Base
{
    virtual void f()
    {
        std::cout << "Base::f" << std::endl;
    }
};

struct Derived : public Base
{
    virtual void f()
    {
        std::cout << "Derived::f" << std::endl;
    }
};

int main()
{
    Base* dp = new Derived;
    auto b1 = *dp;
    auto& b2 = *dp;
    std::cout << typeid(b1).name() << std::endl;
    std::cout << typeid(b2).name() << std::endl;
}

它将打印 Base 和 Derived。
但是为什么 auto& 被评估为对 Derived 的引用而不是对 Base 的引用?
更糟糕的是把代码改成这样:

struct Base{};
struct Derived : public Base{};

int main()
{
    Base* dp = new Derived;
    auto b1 = *dp;
    auto& b2 = *dp;
    std::cout << typeid(b1).name() << std::endl;
    std::cout << typeid(b2).name() << std::endl;
}

返回两种类型的 Base。那么为什么类型依赖于虚函数呢? 我使用的编译器是VS2010。 谁能给我一个提示,我可以在标准中找到这种行为的定义吗?

最佳答案

auto 在这两种情况下都会产生 Base,而不是派生的。在第一种情况下,您正在对对象进行切片(在父级别复制),而在第二种情况下,因为它是一个引用,所以您会得到一个 Base& 到实际的 Derived目的。这意味着所有虚函数调用都将被分派(dispatch)到 Derived 级别的最终覆盖器。

typeid 运算符对多态类型的行为与对非多态类型的行为不同。如果应用于对多态类型的引用,它将在运行时执行类型检查并产生实际对象的类型。如果它应用于对象或对非多态类型的引用,它将在编译时解析为对象或引用的静态类型。

要验证 auto 推断的内容,您可以使用稍微不同的测试:

void test( Base& ) { std::cout << "Base" << std::endl; }
void test( Derived& ) { std::cout << "Derived" << std::endl; }

然后调用该函数并查看它解析为什么类型。我希望编译器选择第一个重载,因为 auto& a = *dp; 应该等同于 Base& a = *dp;

关于c++ - 在 C++0X 中评估 auto 的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6706794/

相关文章:

c++ - 矩阵乘法(不同维度)

c++ - for循环条件中的函数调用?

c++ - 从仿函数模板参数推导出可变参数和返回类型(MSVC 特定)

c++ - 具有默认行为的函数指针

c++ - 如何从对象内部访问变量

c++ - 标准标题上的 Visual Studio 2017 错误

c++ - FFTW 不会返回无穷大以外的值、接近零的值或负无穷大

c++ - 为对象创建 "thin"结构包装器的正确方法是什么?

c++ - 基于模板参数初始化静态字符

c++ - 有没有跨平台的方法来检测 Debug模式编译?