我在连接时遇到一个奇怪的错误。
标题:
global.h
#include <cmath>
#include <iostream>
#include <vector>
#include <blitz/tinyvec2.h>
typedef blitz::TinyVector<double,3> vettore;
#include "animal.h"
animal.h
#ifndef __ANIMAL_H
#define __ANIMAL_H
//! basic data structure for an animal -------------------------
struct Animal
{
int age;
public:
Animal(int _age) : age(_age) {}
};
//! contains info about a pair of animals ----------------------
struct AnimalPairs
{
vettore distance;
AnimalPairs( const vettore& _distance ) : distance(_distance) {}
};
typedef std::vector<AnimalPairs> pair_list;
//! data structure for a group of animals ----------------------
class AnimalVector
{
private:
std::vector<Animal> animals;
pair_list pairs;
public:
AnimalVector( const AnimalVector &other );
};
#endif
以下是*cpp
个文件
的main.cpp
#include "global.h"
int main ()
{
std::cout<< "Hello" << std::endl;
}
animal.cpp
#include "global.h"
AnimalVector::AnimalVector( const AnimalVector &other )
{
pairs = other.pairs;
}
编译我用
g++ main.cpp animal.cpp -I/usr/include/boost -I/fs01/ma01/homes/matc/local/blitz/include
这是我得到的错误:
/tmp/ccGKHwoj.o: In function `AnimalPairs::AnimalPairs(AnimalPairs const&)':
animal.cpp:(.text._ZN11AnimalPairsC2ERKS_[_ZN11AnimalPairsC5ERKS_]+0x1f):
undefined reference to \`blitz::TinyVector<double,
3>::TinyVector(blitz::TinyVector<double, 3> const&)'
collect2: error: ld returned 1 exit status
由于某些原因,如果我将AnimalVector
构造函数设置为inline
,则代码将起作用。
有人能解释我为什么吗?
编辑:
这是blitz/tinyvec2.h
的链接
https://github.com/syntheticpp/blitz/blob/master/blitz/tinyvec2.h
答案 0 :(得分:1)
tinyvec2.cc
是使用tinyvec2.h
中声明的方法时需要包含的文件
我不喜欢命名(一个名为.cc
的包含文件)并且在得到错误之前自己会忽略它。
但是如果你查看那个.cc文件的内容,那么预期的用法就很明确了。
在类似情况下(对文件对的命名规则有很大不同),我使用以下编码习语:
第一个包含文件(他们的.h)包含在需要其中任何一个的任何其他.h文件中。第二个包含文件永远不会包含在其他.h文件中。
如果出现构建错误,指出其中一些缺失,请将第二个包含文件的include包含到任何获取构建错误的.cpp文件中。
该计划非常有效,可以在大型项目中快速保持构建速度,并最大限度地减少复杂交互模板类之间的循环依赖性。但它可能并不完全是将tinyvec2分成两个包含文件的人。
结论:获得链接错误的任何模块都需要在编译时包含.cc文件,但直接与间接相关取决于您。在global.h中包含.cc更简单,最坏的情况会降低你的构建速度(因为.cc与你自己的.h文件没有循环关系)。