模板方法访问前向声明的类仅在没有此指针的情况下无法编译 [英] Template method accesses forward declared class fails to compile only without this pointer
问题描述
当我使用最新的Visual Studio编译以下代码时,编译成功.
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() {}
};
但是当我从 this-> c-&g; g()
中删除 this->
时,编译失败并显示 C2027:使用未定义的类型'C'
.
But when I remove this->
from this->c->g()
, compilation fails with C2027: use of undefined type 'C'
.
当我将方法 f
设为非模板时,无论 this->
是否存在,它都无法编译,因此我认为它与模板编译/实例化,但我真的无法弄清楚.我已阅读此答案,但不是 c
和 g
在 T :: f()
中清楚吗?
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()
?
因此,问题是:这里 this->
的作用是什么?
So, the question is: What's the role of this->
here?
编译器差异:
+-----------------------+---------------------+----------------------+--------------+
| | 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
和 x86-64 clang 9.0.0
已通过Compiler Explorer测试./p>
x64 msvc v19.24
, x86-64 gcc 9.2
and x86-64 clang 9.0.0
are tested with Compiler Explorer.
推荐答案
由于C ++ 17 [temp.res]/8.3,程序是格式错误的NDR:
The program is ill-formed NDR due to C++17 [temp.res]/8.3:
该程序格式错误,如果出现以下情况,则无需进行诊断:
The program is ill-formed, no diagnostic required, if:
- [...]
- 由于模板不依赖于模板参数,因此模板定义后的假想实例化将不正确.
假设的实例化格式不正确,因为当 c
的指针指向不完整类型时使用了 c-> g
,并且不受模板参数<代码> A .
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.
这篇关于模板方法访问前向声明的类仅在没有此指针的情况下无法编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!