Rar*_*ima -3 c++ linker templates visual-c++ c++11
正如标题所述,我遇到了臭名昭著的unresolved external symbol
链接器问题。
我已经移动了.h
文件中的所有内容。模板类不再在.h
和.cpp
文件之间拆分。
我已将它们包含在主文件中。我已经三重四重检查了定义是否存在(显然)。
我的文件如下:
Utils.h
:
只是一个漂亮的 coutvector
和valarray
。测试和工作。
#pragma once
#include <vector>
#include <valarray>
#include <ostream>
using std::vector;
using std::valarray;
using std::ostream;
template <typename ValueType>
ostream& operator<< (ostream&, vector<ValueType>);
template <typename ValueType>
ostream& operator<< (ostream&, valarray<ValueType>);
template <typename ValueType>
ostream& operator<< (ostream& out, vector<ValueType> v)
{
out << "Vec[";
for (int i = 0; i < v.size() - 1; i++)
out << v[i] << ", ";
out << v[v.size() - 1] << "]";
return out;
}
template <typename ValueType>
ostream& operator<< (ostream& out, valarray<ValueType> a)
{
out << "VArr[";
for (int i = 0; i < a.size() - 1; i++)
out << a[i] << ", ";
out << a[a.size() - 1] << "]";
return out;
}
Run Code Online (Sandbox Code Playgroud)
Fitness.h
: 一个简单的类,有几个valarray
s 和一个bool
. 也实现了一个漂亮的cout。测试和工作。
#pragma once
#include <valarray>
#include <ostream>
#include "Utils.h"
using std::valarray;
using std::ostream;
class Fitness {
public:
class FitnessNotValidException : public std::exception {};
class ValueIndexTooLargeException : public std::exception {};
class IncorrectNewValuesLength : public std::exception {};
private:
const valarray<double> weights;
bool valid;
valarray<double> values;
public:
Fitness(const valarray<double>&);
static Fitness max();
static Fitness min();
double WeightedFitness();
const valarray<double>& Weights();
bool Valid();
void Valid(bool);
void invalidate();
void validate();
const valarray<double>& Values();
void Values(int, double);
void Values(const valarray<double>&);
double Value();
void Value(double);
friend ostream& operator<< (ostream&, Fitness);
};
// Implementation for everything...
ostream& operator<<(ostream & out, Fitness fit)
{
out << "Fitness[W:" << fit.weights << ", V:" << fit.values << ", valid:" << fit.valid << "]";
return out;
}
Run Code Online (Sandbox Code Playgroud)
Individual.h
: 具有Fitness
成员的模板类。还实现了“pretty-cout”。
#pragma once
#include <ostream>
#include <valarray>
#include "Fitness.h"
using std::ostream;
template <typename GeneType>
class Individual
{
private:
Fitness fitness;
GeneType genes;
public:
Individual(Fitness, GeneType);
Fitness& Fitness();
GeneType& Genes();
Individual<GeneType> copy();
friend ostream& operator<< (ostream&, Individual<GeneType>);
};
// Implementation for everything...
template<typename GeneType>
ostream& operator<<(ostream& out, Individual<GeneType> ind)
{
out << "Individual[G:" << ind.genes << ", F:" << ind.fitness << "]";
return out;
}
Run Code Online (Sandbox Code Playgroud)
所有这 3 个文件都以相同的顺序包含在主文件中。如果我尝试打印个人的基因和健康状况,一切都很好:
Individual<valarray<int>> ind = ind_builder.build();
cout << ind.Fitness() << endl << ind.Genes() << endl;
/*
Fitness[W:VArr[1], V:VArr[0], valid:0]
VArr[0, 0, 0, 1, 0, 1, 1, 1, 0, 1]
*/
Run Code Online (Sandbox Code Playgroud)
意思是<<
for valarray
,Fitness
有效,所以我在<<
应该如何工作的概念上没有任何错误。但是当我尝试:cout << ind << endl;
错误 LNK2019:未解析的外部符号“类 std::basic_ostream > & __cdecl operator<<(class std::basic_ostream
&,class Individual >)" (??6@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV01@V?$Individual@V?$valarray@H@std@@@@ @Z) 在函数 main 中引用
我不明白问题出在哪里。在包括似乎是为了和之间不存在分裂问题.h
和.cpp
。有没有我应该知道的另一个模板问题?因为除了总是推荐的解决方案(例如将所有代码移动到.h
文件中)之外,我一直在寻找解决方案几天,但没有成功。
operator <<
定义与operator <<
友元声明不匹配,请注意,operator <<
定义实际上是一个模板,因此不如未实现的非模板友元更受欢迎。所以你会收到链接器错误,因为编译器插入了对非模板非实现友元函数的调用。也operator <<
应该通过 const 限定的引用来获取对象。
你应该避免friend
,但如果你仍然要使用它,声明应该是
template <typename GeneType>
class Individual;
template<typename GeneType>
ostream & operator <<(ostream &, Individual<GeneType> const & individual);
template <typename GeneType>
class Individual
{
template<typename GeneTypeInner>
friend ostream & operator <<(ostream &, Individual<GeneTypeInner> const & individual);
};
template<typename GeneType>
ostream & operator<<(ostream& out, Individual<GeneType> const & individual)
{
out << "Individual[G:" << individual.genes << ", F:" << individual.fitness << "]";
return out;
}
Run Code Online (Sandbox Code Playgroud)