当我使用最新的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:使用未定义类型“C”
。
当我将方法f
设为非模板函数时,无论是否出现this->
,都无法编译通过,因此我认为这与模板的编译/实例化相关,但我真的无法确定。我已阅读此答案,但在T::f()
中,c
和g
不是不含糊的吗?
所以,问题是: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
。
T.f<int>()
第一次被实例化时,它还没有C
的定义,因此应该失败。 - ChrisMMT
不依赖于A
,因此this
不依赖于A
,因此对c
的访问不依赖于A
,因此在C
中访问g
不依赖于A
,因此应该在模板的定义处进行检查而不是在实例化时进行,因此模板本身就是有问题的。如果在模板定义处可见C
的定义,则它将是良好的形式。 - HTNWthis->c->g()
不在模板定义中使用,只在T::f()
定义中使用。由于c
(带或不带this
)尚未具有C
的完整定义,因此仍然是错误的。所以,是的,不像我在第一条评论中说的那样,不是T.f<int>()
的实例化。而是在定义T::f()
时。 - ChrisMM