为什么自动返回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())
不能编译; Foo
的operator()
成员函数不可见。 我认为这是因为基类模板在Foo
完全定义之前被实例化。
令人惊讶的是,如果我放置auto
返回types它编译。 我认为auto
会让编译器从函数体中推断返回types,并失败 – 因为主体使用未完全定义的Foo
types。
对于MSVC 2015.3和Clang 3.8,这种行为是相同的
为什么代码开始使用auto
? auto
types扣除莫名其妙地“延迟”实例吗? 或者使用与手写返回typesexpression式不同的上下文?
你的猜测是正确的。 推导出的返回types直到需要函数的签名才被实际推导出来。 这意味着它将在调用getCallOperator
的上下文中getCallOperator
,此时Foo
被完全定义。
这在7.1.6.4p12中指定:
即使函数体包含具有非types依赖操作数的返回语句,也会在实例化定义时发生带有占位符的函数模板的返回types推导。