类模板上一个特定函数的未解析外部符号

Rar*_*ima -3 c++ linker templates visual-c++ c++11

正如标题所述,我遇到了臭名昭著的unresolved external symbol链接器问题。

我已经移动了.h文件中的所有内容。模板类不再在.h.cpp文件之间拆分。

我已将它们包含在主文件中。我已经三重四重检查了定义是否存在(显然)。

我的文件如下:

Utils.h

只是一个漂亮的 coutvectorvalarray。测试和工作。

#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: 一个简单的类,有几个valarrays 和一个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 valarrayFitness有效,所以我在<<应该如何工作的概念上没有任何错误。但是当我尝试: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文件中)之外,我一直在寻找解决方案几天,但没有成功。

use*_*670 5

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)