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

问题描述 投票:4回答:1

当我使用最新的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->中删除this->c->g()时,编译失败并显示C2027: use of undefined type 'C'

当我使方法f成为非模板时,无论this->存在与否,它都无法编译,因此我认为它与模板的编译/实例化有关,但我无法弄清楚。我已经读过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++ templates this language-lawyer forward-declaration
1个回答
0
投票

由于C ++ 17 [temp.res] /8.3,程序是格式错误的NDR:

该程序格式错误,不需要诊断,如果:

  • [...]
  • 由于其不依赖于模板参数的构造,因此紧随其定义的模板的假想实例化将是不正确的,

由于c->g具有指向不完整类型的指针,并且不受模板参数c的影响,所以使用A是假设的实例化。)>

因此是否引发错误是实现质量的问题。

© www.soinside.com 2019 - 2024. All rights reserved.