为什么自动返回types扣除没有完全定义的types工作?

考虑以下:

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(); } 

我想根据派生类中operator()签名在CRTP基类中创build一个返回types的成员函数。 然而decltype(&Der::operator())不能编译; Foooperator()成员函数不可见。 我认为这是因为基类模板在Foo完全定义之前被实例化。

令人惊讶的是,如果我放置auto返回types它编译。 我认为auto会让编译器从函数体中推断返回types,并失败 – 因为主体使用未完全定义的Footypes。

对于MSVC 2015.3和Clang 3.8,这种行为是相同的

为什么代码开始使用autoautotypes扣除莫名其妙地“延迟”实例吗? 或者使用与手写返回typesexpression式不同的上下文?

你的猜测是正确的。 推导出的返回types直到需要函数的签名才被实际推导出来。 这意味着它将在调用getCallOperator的上下文中getCallOperator ,此时Foo被完全定义。

这在7.1.6.4p12中指定:

即使函数体包含具有非types依赖操作数的返回语句,也会在实例化定义时发生带有占位符的函数模板的返回types推导。