【问题标题】:incomplete class usage with auto in template class在模板类中使用 auto 的类使用不完整
【发布时间】: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。

标签: c++ templates language-lawyer auto incomplete-type


【解决方案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,编辑修复
猜你喜欢
  • 2011-11-04
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 2019-06-21
  • 2019-09-25
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多