【发布时间】:2013-11-06 22:48:32
【问题描述】:
我(模糊地)知道如果一个模板没有 使用,它就不会被实例化。例如,即使T::type 在T = int 时没有意义,以下代码也能正常编译。
template<typename T>
struct A
{
void f() { using type = typename T::type; }
};
A<int> a; //ok
它编译是因为f() 没有使用,所以它没有被实例化——因此T::type 的有效性没有被检查。其他一些 member 函数 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
这也是compile fines。但是在这里我意识到我对“使用”的定义的理解是模糊的。请问:
-
f()还没有使用吗?具体如何?
我可以清楚地看到它在g() 内部使用。但是后来我想,由于没有使用g(),所以从实例化的角度来看,也没有使用f()。这似乎足够合理。到目前为止。
但是,如果我将 virtual 关键字添加到 g(),它不会编译:
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
它导致compilation error,因为现在它尝试实例化f()。我不明白这种行为。
谁能解释一下?特别是virtual关键字对类模板成员“使用”定义的影响。
【问题讨论】:
-
如果我没记错的话,
virtual强制实例化成员函数,因为现在几乎不可能静态评估是否会使用此函数。在实践中,您要求创建一个充满函数指针的 v 表......所以函数需要存在,以便我们可以获取指向它的指针。 -
结构模板只有在你使用它时才会被实例化。它要么是整个结构,要么什么都没有。它与 g 或 f 没有任何关系。
-
@Sarien:确实如此,模板类的成员函数只有在使用 ODR 时才会被实例化。
-
@Sarien:即使你不使用它们,实例化所有成员也是非常愚蠢的。幸运的是,C++ 很聪明,并且只实例化你使用的东西。
-
真的吗?哇,不知道。
标签: c++ templates c++11 virtual instantiation