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

徘徊边缘 提交于 2021-01-27 06:54:27

问题


When I compile the following code with the latest Visual Studio, it success to compile.

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() {}
};

But when I remove this-> from this->c->g(), compilation fails with C2027: use of undefined type 'C'.

When I make the method f non-template, it fails to compile no matter this-> presents or not, so I think it's related to template compiling/instantiating, but I can't really figure out. I've read this answer, but isn't c and g unambiguous in T::f()?

So, the question is: What's the role of this-> here?


Compiler Differences:

+-----------------------+---------------------+----------------------+--------------+
|                       | 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.24, x86-64 gcc 9.2 and x86-64 clang 9.0.0 are tested with Compiler Explorer.


回答1:


The program is ill-formed NDR due to C++17 [temp.res]/8.3:

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,

The hypothetical instantiation is ill-formed because c->g is used when c has pointer to incomplete type, and that is not affected by the template parameter A.

So it is a quality of implementation issue whether an error is raised.



来源:https://stackoverflow.com/questions/60215335/template-method-accesses-forward-declared-class-fails-to-compile-only-without-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!