当我使用最新的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,但是在c
中g
和T::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.24
,x86-64 gcc 9.2
和x86-64 clang 9.0.0
已通过Compiler Explorer测试。
由于C ++ 17 [temp.res] /8.3,程序是格式错误的NDR:
该程序格式错误,不需要诊断,如果:
- [...]
- 由于其不依赖于模板参数的构造,因此紧随其定义的模板的假想实例化将是不正确的,
由于c->g
具有指向不完整类型的指针,并且不受模板参数c
的影响,所以使用A
是假设的实例化。)>
因此是否引发错误是实现质量的问题。