我(模糊地)知道,如果没有使用,模板将不会被实例化。例如,即使当T = int时,下面的代码也可以编译通过,因为T :: type在这种情况下是无意义的。
它能够编译是因为
它导致编译错误,因为现在它试图实例化
有人能解释一下吗?特别是
template<typename T>
struct A
{
void f() { using type = typename T::type; }
};
A<int> a; //ok
它能够编译是因为
f()
没有被使用,所以它没有被实例化 - 因此T::type
的有效性仍未经检查。即使其他一些成员函数g()
调用f()
也无所谓。template<typename T>
struct A
{
void f() { using type = typename T::type; }
void g() { f(); } //Is f() still unused?
};
A<int> a; //ok
这也会编译罚款。但是在这里我意识到了我对"使用"定义的模糊理解。我问:
f()
仍然未被使用吗?具体来说是怎样的?
我可以清楚地看到它在g()
内部被使用。但是我想,由于g()
没有被使用,从实例化的角度来看,f()
也没有被使用。这似乎已经足够合理。
但是如果我给g()
添加virtual
关键字,它将无法编译:
template<typename T>
struct A
{
void f() { using type = typename T::type; }
virtual void g() { f(); } //Now f() is used? How exactly?
};
A<int> a; //error
它导致编译错误,因为现在它试图实例化
f()
。我不理解这种行为。有人能解释一下吗?特别是
virtual
关键字对类模板成员的"use"定义的影响。
virtual
强制实例化成员函数,因为现在静态地评估这个函数是否会被使用几乎是不可能的。实际上,你要求创建一个填充有指向函数的指针的虚函数表... 所以这个函数需要存在,这样我们才能取一个指向它的指针。 - Matthieu M.