在模板类中使用 auto 的类使用不完整

Posted

技术标签:

【中文标题】在模板类中使用 auto 的类使用不完整【英文标题】:incomplete class usage with auto in template class 【发布时间】:2019-03-15 22:48:57 【问题描述】:

以下代码格式正确吗?

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 失败

【问题讨论】:

这个简化版是同一个问题吗? godbolt.org/z/9V4fx7 注意:gcc 编译; clang 报错。 @RichardCritten:不确定,你的函数是模板,而我的是类模板的友元函数。 @RichardCritten,同样,Jarod42 代码适用于 gcc 和 clang。 【参考方案1】:

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

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

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

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

所以对于B,第一条规则的格式不正确。但是对于auto,在函数实例化之前不会进行推导......此时类型已完成,所以没关系。

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


从技术上讲,上述措辞不适用于这种情况。我们没有函数模板。但目的是让它适用于任何类型的模板化事物。有一个 PR 可以编辑地解决这个问题:

带有占位符 [...]

函数模板 的返回类型推导

收件人:

作为函数或函数模板的模板化实体的返回类型推导,其中包含占位符

这里适用。

【讨论】:

f 这里不是函数模板(类模板的友元函数),但我想是一样的。 @Jarod42 是的,这可能是措辞问题。 这是否意味着没有auto (C++98) 就无法让它工作? @alfC 定义内联非会员朋友?没有。 @Jarod42 github.com/cplusplus/draft/pull/2350,编辑修复

以上是关于在模板类中使用 auto 的类使用不完整的主要内容,如果未能解决你的问题,请参考以下文章

如何使用在同一类的基模板中的类中声明的枚举

部分模板类中不允许指向不完整类类型的指针

std::auto_ptr 在我的模板类中编译,但不是 std::unique_ptr

类中的模板函数

类模板的概念和意义

第58课 类模板的概念和意义