C ++未定义对链接函数的引用

时间:2013-05-14 19:03:27

标签: c++ templates g++

我在链接C ++项目时遇到问题,我无法弄清楚是什么问题。 代码的开玩笑。

clitest.cpp

#include <iostream>
#include "node.h"
using namespace std;

int main(int argc, char** argv)
{
    node<int> *ndNew = new node<int>(7);
    return 0;
}

node.h

#ifndef NODE_H
#define NODE_H
#include <vector>

template <typename T>
class node
{
    private:
        node<T>* ndFather;
        std::vector<node<T>* > vecSons;
    public:
        T* Data;
        node(const T &Data);
};
#endif

node.cpp

#include "node.h"

using namespace std;

template <typename T>
node<T>::node(const T &Data)
{
    this->Data = &Data;
    this->ndFather = 0;
    this->vecSons = (new vector<T>());
};

使用的编译器命令是

g++ -Wall -g clitest.cpp node.cpp -o clitest

错误日志就像这样

clitest.cpp: In function ‘int main(int, char**)’:
clitest.cpp:8:16: warning: unused variable ‘ndNew’ [-Wunused-variable]
     node<int> *ndNew = new node<int>(7);
                ^
/tmp/cc258ryG.o: In function `main':
clitest.cpp:8: undefined reference to `node<int>::node(int const&)'
collect2: error: ld returned 1 exit status
make: *** [blist] Error 1

我花了相当多的时间来转移代码,试图找出问题,我要么错过了一些基本的东西,要么就是我不了解C ++链接的东西。

2 个答案:

答案 0 :(得分:0)

在.cpp文件之前使用-I.,以便编译器知道查找.h文件。

g++ -Wall -I. clitest.cpp node.cpp -o clitest

或只是-I

g++ -Wall -I clitest.cpp node.cpp -o clitest

答案 1 :(得分:0)

使用模板时,编译器需要知道如何在实例化时为类生成代码。导致未定义的引用错误,因为编译器未生成node<int>::node(int const &)构造函数。见,例如, Why can templates only be implemented in the header file?

您有几个选择:

  1. 将实现放在node.h中(node.cpp被删除,因为它不需要)
  2. 将实现放在node.h底部的#included文件中(通常该文件名为node.tpp)
  3. 我建议将实现放在node.h中并删除node.cpp。请注意,示例中的代码无效c ++:成员变量vecSons不是指针,因此行vecSons = new vector<T>()将给出编译器错误。以下代码可以作为完整实现的起点:

    #ifndef NODE_H
    #define NODE_H
    #include <vector>
    
    template <typename T>
    class node
    {
        private:
            node<T>* ndFather;
            std::vector<node<T>* > vecSons;
        public:
            const T* Data;
            node(const T &d) : 
                ndFather(0),
                vecSons(),
                Data(&d)
            {
            }
    };
    #endif