模板方法访问前向声明 class 仅在没有此指针的情况下无法编译

Template method accesses forward declared class fails to compile only without this pointer

当我用最新的Visual Studio编译以下代码时,编译成功。

class C;

class T
{
public:
    template<typename A>
    void f();

private:
    C* c;
};

int main()
{
    T t;
    t.f<int>();
}

template<typename A>
void T::f()
{
    this->c->g();
}

class C
{
public:
    void g() {}
};

但是当我从 this->c->g() 中删除 this-> 时,编译失败 C2027: use of undefined type 'C'

当我将方法f设为非模板时,无论this->出现与否,它都编译失败,所以我认为它与模板compiling/instantiating有关,但我可以真的想不通。我读过 this answer,但 cgT::f() 中不是明确的吗?

所以,问题是:这里this->的作用是什么?


编译器差异:

+-----------------------+---------------------+----------------------+--------------+
|                       | Template, w/ this-> | Template, w/o this-> | Non-Template |
+-----------------------+---------------------+----------------------+--------------+
| Visual Studio 16.3.10 | Success             | Fail                 | Fail         |
| x64 msvc v19.24       | Success             | Success              | Fail         |
| x86-64 gcc 9.2        | Success w/ warning  | Success w/ warning   | Fail         |
| x86-64 clang 9.0.0    | Fail                | Fail                 | Fail         |
+-----------------------+---------------------+----------------------+--------------+

x64 msvc v19.24x86-64 gcc 9.2x86-64 clang 9.0.0 已使用 Compiler Explorer 进行测试。

由于 C++17 [temp.res]/8.3:

,该程序是格式错误的 NDR

The program is ill-formed, no diagnostic required, if:

  • [...]
  • a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter,

假设的实例化是错误的,因为当 c 具有指向不完整类型的指针时使用 c->g,并且不受模板参数 A 的影响。

所以是否报错是实现质量问题。