1

如果我有一个类模板,并且我使用指向专用实例的动态分配实例的智能指针,这是否会导致整个类模板由编译器定义,或者它是否还会等待从指针调用成员函数在实例化之前?

template <class T>
class Test {
    public:
        void nothing();
        void operation();

        static const int value;
};

template <class T>
const int Test<T>::value = 100;

template <class T>
void Test<T>::nothing() {
   /* invalid code */
   int n = 2.5f;
}

template <class T>
void Test<T>::operation() {
    double x = 2.5 * value;
}

int main() {
    std::unique_ptr<Test<int>> ptr = new Test<int>();  // mark1
    ptr->operation(); // mark2
    return 0;
}
  1. 整个类模板是否在 mark1 处实例化?

  2. 如果不是,这是否意味着此代码将正确编译并且成员函数 Test::nothing() 不会被实例化?

4

3 回答 3

1

整个类模板是否在 mark1 处实例化?

是的。类模板是隐式实例化的——只有类模板,而不是它的所有成员。

如果不是,这是否意味着此代码将正确编译并且成员函数 Test::nothing() 不会被实例化?

not并不意味着,如果不nothing()使用,则不实例化。

于 2013-11-06T19:38:38.677 回答
0

对此的完整答案可能在很大程度上取决于您使用的编译器。

//mark1处,编译器会注意到类的至少一部分Test<int>需要实例化。它是在当时还是在以后的阶段完成,取决于编译器设计者。

At //mark2,Test<int>.operation()显然是需要的,它要么被标记以供以后实例化,要么在现场创建,这再次取决于编译器设计者的决定。

由于Test<int>.nothing()从未被引用,编译器可以自由地实例化或不实例化它。一些较旧的编译器盲目地实例化整个类,但我怀疑大多数现代编译器只会实例化他们可以证明是必要的(或者至少他们不能证明是不必要的)。但是,在编译器中发生这种情况的位置再次取决于编译器设计者构建编译器的方式。

于 2013-11-06T19:53:21.720 回答
0

因此,对于我正在使用的编译器(MS Visual C++),我的假设是正确的,对于问题中提供的代码,类模板成员实例化不会发生在//mark1,而是发生在//mark2并且Test<int>.nothing()不会发生由编译器创建。

但是,我似乎遗漏了我遇到的问题的关键部分。我的实际类是虚拟层次结构的一部分,根据 MSDN 帮助库,所有虚拟成员都在对象创建时实例化。因此,在上面的示例中,如果两个成员函数(即operation()nothing())都是虚拟的,那么//mark2编译器会尝试为这两个函数生成代码,并且验证nothing()会失败。

http://msdn.microsoft.com/en-us/library/7y5ca42y.aspx

http://wi-fizzle.com/howtos/vc-stl/templates.htm#t9

于 2014-05-13T08:12:29.797 回答