以下代码格式正确吗?
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失败
答案 0 :(得分:8)
在函数定义的上下文中,参数的类型或函数定义的返回类型不得为不完整或抽象的(可能具有cv限定的)类类型,除非删除该函数([dcl.fct.def.delete])。
实例化定义时,即使函数主体包含带有与类型无关的操作数的
return
语句,在声明的类型中具有占位符的函数模板也会进行返回类型推导。
因此,对于B
,它受第一个规则的影响。但是使用auto
时,直到函数实例化之后才进行推论...到那时类型是完整的,就可以了。
请注意,第一个规则仅适用于定义,这就是do_f()
没问题的原因。您可以具有返回不完整类型的声明。
以上措辞从技术上讲不适用于这种情况。我们没有功能模板。但其目的是将其应用于任何类型的模板化对象。有PR可以通过以下方式编辑此问题:
具有占位符[...]
的功能模板的返回类型推导
收件人:
是功能模板或功能模板的模板实体的返回类型推论,在其中
这里确实适用。