【问题标题】:Why does auto return type deduction work with not fully defined types?为什么自动返回类型推导适用于未完全定义的类型?
【发布时间】:2016-11-14 12:13:51
【问题描述】:

考虑以下几点:

template<typename Der>
struct Base {
    // NOTE: if I replace the decltype(...) below with auto, code compiles
    decltype(&Der::operator()) getCallOperator() const {
        return &Der::operator();
    }
};

struct Foo : Base<Foo> {
    double operator()(int, int) const {
        return 0.0;
    }
};

int main() {
    Foo f;
    auto callOp = f.getCallOperator();
}

我想在 CRTP 基类中创建一个成员函数,其返回类型取决于派生类中 operator() 的签名。但是decltype(&amp;Der::operator()) 编译失败; Foo 中的 operator() 成员函数不可见。我假设这是因为基类模板是在 Foo 完全定义之前实例化的。

令人惊讶的是,如果我将 auto 放置为它编译的返回类型。我假设auto 会使编译器从函数体中推断出返回类型并失败——因为函数体使用了未完全定义的Foo 类型。

MSVC 2015.3 和 Clang 3.8 的此行为相同

为什么代码开始使用autoauto 类型推断是否以某种方式“延迟”实例化?或者使用与手写返回类型表达式不同的上下文?

【问题讨论】:

  • 好问题。赞成。
  • 同一个问题,但问答的角度略有不同。这里我们有“自动演绎的不同之处”,链接的问题及其答案更多的是关于“我怎样才能使手写表达起作用”。虽然它可能仍然符合重复的条件......

标签: c++ c++14 crtp return-type-deduction


【解决方案1】:

你的猜测是正确的。在需要函数签名之前,不会实际推导出推导的返回类型。这意味着它将在调用getCallOperator 的上下文中推断出来,此时Foo 已完全定义。

这是在 7.1.6.4p12 中指定的:

当定义被实例化时,即使函数体包含带有非类型相关操作数的 return 语句,在其声明类型中具有占位符的函数模板的返回类型推导也会发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2014-02-11
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多