Не будет ссылки, если не метод встраивания

Я сталкиваюсь со странной ошибкой при связывании времени.

Заголовки:

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

1 ответ

Решение

tinyvec2.cc это файл, который нужно включить, когда вы используете методы, объявленные в tinyvec2.h

Мне не нравится это имя (включаемый файл с именем .cc) и сам бы не обратил на это внимания, прежде чем получил ошибку, которую получил.

Но если вы посмотрите на содержимое этого файла.cc, предполагаемое использование ясно.

В похожих ситуациях (с очень разными правилами именования для пар файлов) я использую следующую кодировку:

Первый включаемый файл (их.h) включается любым другим файлом.h, который нуждается в этом. Второй включаемый файл никогда не включается другими файлами.h.

Когда вы получаете ошибку сборки, указывающую на то, что какая-то из них отсутствует, добавьте включение второго файла включения в любой файл.cpp, который получает ошибку сборки.

Этот план очень эффективен для поддержания высокой скорости сборки в мегапроектах и ​​минимизации циклической зависимости между сложными взаимодействующими классами шаблонов. Но это может быть не совсем то, что имел в виду тот, кто разделил tinyvec2 на два включаемых файла.

Итог: любой модуль, получивший ошибку ссылки, которую вы видели, должен иметь файл.cc, включенный во время компиляции, но прямо или косвенно зависит от вас. Включение.cc в ваш global.h проще и в худшем случае замедлит вашу скорость сборки (потому что этот.cc не имеет циклических связей с вашими.h файлами).

Другие вопросы по тегам