VS 2011模板类

时间:2012-05-07 07:02:59

标签: c++ visual-studio templates

我有一个相当标准的情况,我希望以下列方式使用模板化的类:

  1. 定义.h文件
  2. 包括.cpp
  3. 在我尝试的每个其他编译器(即g ++和clang / llvm)中,这都可以正常工作。在visual studio中,它告诉我文件已经定义。

    如果我手动剪切并将.cpp中的文本粘贴到.h文件中,那么一切正常。我的印象是,这正是#include应该做的。

    我的预感是,visual studio正在以某种方式不止一次地编译.cpp文件(虽然我将#pragma once放在.h和.cpp文件上。)

    发生了什么,以及如何让我的模板类在VS中运行?

    代码如下:
    .h:

    #pragma once
    template <class T>
    class myVector
    {
    private:
        void grow();
    public:
    int size;
    int index;
    T** words;
    void pushBack(T* data);
    inline T* operator[](int);
    myVector(void);
    ~myVector(void);
    };
    
    #include "myVector.cpp"
    

    的.cpp:

    #pragma once
    #include "stdafx.h"
    #include <cstdlib>
    #include "myVector.h"
    #include <iostream>
    using namespace std;
    
    template<class T>
    myVector<T>::myVector(void)
    {
        this->size = 2000;
        words = new T*[size];
        index=0;
    }
    
    template<class T>
    void myVector<T>::pushBack(T* input)
    {
        if(index<size)
        {
            words[index]=input;
        }
        else
        {
            grow();
            words[index]=input;
        }
        index++;
    }
    
    template<class T>
    T* myVector<T>::operator[](int i)
    {
        return words[i];
    }
    
    template<class T>
    void myVector<T>::grow()
    {
        //cout<<"I grew:"<<endl;
        size*=2;
        words = (T**)realloc(words,size*sizeof(T*));
    }
    
    template<class T>
    myVector<T>::~myVector(void)
    {
        delete[] words;
    }    
    

1 个答案:

答案 0 :(得分:2)

在我看来,你的困惑源于不知道#pragma once和翻译单位的运作方式。

#pragma once,就像包含警卫一样,可以防止将文件内容(通常是标题)多次拉入单个翻译单元。

如果您在多个实施文件中#include <vector>,则会在所有文件中提取内容,但每个翻译单元只会提取一次。

所以你应该删除#include "myVector.cpp",因为MSVS会自动编译实现文件,而且它也是错的。

请注意,模板定义必须是可见的,因此您需要将其移至.h文件,就像您一样,或者使用您当前的方法重命名.cpp将文件归档为.impl甚至.h,并将其包含在内。

相关问题