不完整 class 在模板 class 中使用 auto

incomplete class usage with auto in template class

下面的代码格式正确吗?

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

如果我将 #1​​ 中的 auto 更改为 B,我会收到不完整的类型错误消息。

使用 auto 编译 gcc/clang Demo

失败 B Demo

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

The type of a parameter or the return type for a function definition shall not be an incomplete or abstract (possibly cv-qualified) class type in the context of the function definition unless the function is deleted ([dcl.fct.def.delete]).

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

Return type deduction for a function template with a placeholder in its declared type occurs when the definition is instantiated even if the function body contains a return statement with a non-type-dependent operand.

因此对于 B,根据第一条规则,它的格式不正确。但是对于 auto,在函数被实例化之前,推导不会发生......到那时类型已经完成,所以没问题。

请注意,第一条规则仅适用于定义,这就是 do_f() 没问题的原因。您可以有 return 不完整类型的声明。


上述措辞在技术上不适用于这种情况。我们没有函数模板。但目的是让它适用于任何类型的模板化事物。有一个 PR 可以从以下位置编辑修复此问题:

Return type deduction for a function template with a placeholder [...]

收件人:

Return type deduction for a templated entity that is a function or function template with a placeholder in its

此处适用。