错误C2995:已定义函数模板

error C2995:function template has already been defined

本文关键字:定义 函数模板 C2995 错误      更新时间:2023-10-16

这个问题有很多解决方案,但没有什么能回答我的问题。

我正在使用VS2008.我正在字符串创建一个使用二进制搜索树的地图

#ifndef _map_h
#define _map_h

#include<string>
using namespace std;
template <typename ValType>
class Map
{
    public:
        Map();
        ~Map();
        ValType getvalue(string key);
        void add(string key,ValType value);
    private:
        struct node{
            string key;
            ValType value;
            node *right;
            node *left;
        };
        node *root;
        node *treeSearch(string key,node *t);
        void treeEnter(string key,ValType value,node *&t);
};
#include"map.cpp"
#endif

映射.cpp

#include<string>
#include<iostream>
#include"map.h"
using namespace std;
template <typename ValType>
Map<ValType>::Map(){
    root=NULL;
}
template <typename ValType>
Map<ValType>::~Map(){
    delete root;
}

template <typename ValType>
ValType Map<ValType>::getvalue(string key){
    node *found=treeSearch(key,root);
    if(found==NULL)
        cout<<"Couldnot Found the node";
    else return found->value;
}
template <typename ValType>
typename Map<ValType>::node *Map<ValType>::treeSearch(string key,node *t){
    if(t==NULL) return NULL;
    if(t->key==key) return t;
    if(t->key>key) treeSearch(key,t->left);
    else treeSearch(key,t->right);
}
template <typename ValType>
void Map<ValType>::add(string key,ValType value){
    treeEnter(key,value,root);
}
template <typename ValType>
void Map<ValType>::treeEnter(string key,ValType value,node *&t){
    if(t==NULL){
        t->value=value;
        t->key=key;
        t->left=NULL;
        t->right=NULL;
    }
    else if(t->key==key) t->value=value;
    else if(t->key>key) treeEnter(key,value,t->left);
    else treeEnter(key,value,t->right);
}

错误:对于所有的函数,它表示它们已经被定义。

我正在学习斯坦福大学的在线课程,同样的课程也适用于讲师(她使用的是mac)

您已将map.h包含在map.cpp中,将map.cpp包含在map.h中。map.h中的include保护将防止map.h的多次包含,并将防止无限递归包含。但是,如果您将map.cpp直接提供给编译器(这显然是您想要做的),它将包含map.h一次,然后map.h将再包含map.cpp本身一次。这就是导致错误的原因。

如果您想将模板实现为包含在.h文件中的.cpp文件,您可以这样做。这很奇怪,但它可以被迫工作。首先,如果您决定将#include编译为map.cpp,那么甚至不要尝试编译map.cpp。不要将map.cpp直接提供给编译器。另外,从.cpp文件中删除#include "map.h"。这样做毫无意义。

您的程序将有其他实现文件,比如myprogram.cpp,它将使用您的映射。myprogram.cpp应该包括map.hmyprogram.cpp就是您将要提供给编译器的内容。这样,它将按预期工作。但是尝试直接编译map.cpp只会导致错误。

不过,最好不要在.cpp文件中放入任何内容。将所有内容放入.h文件中,或者,如果您真的想以这种方式拆分,请将.cpp文件重命名为其他文件,以向所有人表明这不是一个翻译单元。

在我的例子中,我在定义模板函数的标头顶部错过了一次include guards或#pragma。