模板类中auto不完整的类使用情况

Jar*_*d42 10 c++ templates language-lawyer incomplete-type auto

以下代码是否形成良好?

class B;

template<class T>
class A
{
    B do_f() const;
    friend auto f(A const& a) {return a.do_f();} // #1
};

class B{};

template <class T>
B A<T>::do_f() const { return B{};}

int main()
{
    A<double> a;
    f(a);
}
Run Code Online (Sandbox Code Playgroud)

如果我改变auto了#1 B,我得到了不完整的类型错误消息.

编译auto为gcc/clang 演示

演示失败B

Bar*_*rry 8

[dcl.fct.def.general]/2:

除非删除该函数,否则函数定义的参数类型或函数定义的返回类型不应是函数定义上下文中的不完整或抽象(可能是cv限定的)类类型([dcl.fct.def.delete] ).

但是[dcl.spec.auto]/10:

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

因此B,第一条规则是不正确的.但是auto,在函数实例化之前不会进行演绎...到那时类型是完整的,所以没关系.

请注意,第一条规则仅适用于定义,这就是为什么do_f()可以.您可以拥有返回不完整类型的声明.


上述措辞在技术上不适用于这种情况.我们没有功能模板.但意图是它适用于任何模板化的东西.有一个PR来编辑修复此问题:

带占位符的函数模板的返回类型推导[...]

至:

模板化实体的返回类型推导,它是一个函数或函数模板,其中包含占位符

这适用于此处.