gpt4 book ai didi

c++ - 为什么这个 c++ 代码不能在 g++ 4.8.2 中编译

转载 作者:行者123 更新时间:2023-11-30 03:59:18 26 4
gpt4 key购买 nike

我正在尝试使用 g++ 4.8.2(Ubuntu 14.04 环境)编译 C++ 脉冲国际象棋引擎 [0]。

我在链接阶段遇到以下错误:

Linking CXX executable pulse-
CMakeFiles/pulse.dir/main.cpp.o: In function `pulse::MoveGenerator::MoveGenerator()':
/home/user/cpp/movegenerator.h:15: undefined reference to `pulse::MoveList<pulse::MoveEntry>::MoveList()'
libcore.so: undefined reference to `pulse::MoveList<pulse::MoveEntry>::rateFromMVVLVA()'
libcore.so: undefined reference to `pulse::MoveList<pulse::RootEntry>::sort()'
libcore.so: undefined reference to `pulse::MoveList<pulse::RootEntry>::MoveList()'
libcore.so: undefined reference to `pulse::MoveList<pulse::MoveEntry>::sort()'
collect2: error: ld returned 1 exit status

当我运行命令时:

g++ -std=c++11 -c movelist.cpp && nm movelist.o | grep sort

我得到输出

0000000000000000 W _ZN5pulse8MoveListINS_9MoveEntryEE4sortEv
0000000000000000 W _ZN5pulse8MoveListINS_9RootEntryEE4sortEv

使用4.9.1时,使用4.8.2时无输出。

为什么g++ 4.9.1会生成sort函数而4.8.2不会,是编译器的bug还是pulse源码的bug?

编辑:

正如指出的重复问题“为什么模板只能在头文件中实现?”中所述,我不明白,它在 g++ 4.9.1 中如何工作?移动列表标题:

#include "value.h"
#include "move.h"

#include <array>
#include <memory>

namespace pulse {

/**
* This class stores our moves for a specific position. For the root node we
* will populate pv for every root move.
*/
template<class T>
class MoveList {
private:
static const int MAX_MOVES = 256;

public:
std::array<std::shared_ptr<T>, MAX_MOVES> entries;
int size = 0;

MoveList();

void sort();
void rateFromMVVLVA();
};

class MoveVariation {
public:
std::array<int, Depth::MAX_PLY> moves;
int size = 0;
};

class MoveEntry {
public:
int move = Move::NOMOVE;
int value = Value::NOVALUE;
};

class RootEntry : public MoveEntry {
public:
MoveVariation pv;
};

}

移动列表来源:

#include "movelist.h"

#include <cassert>

namespace pulse {

template class MoveList<MoveEntry>;
template class MoveList<RootEntry>;

template<class T>
MoveList<T>::MoveList() {
for (unsigned int i = 0; i < entries.size(); ++i) {
entries[i] = std::shared_ptr<T>(new T());
}
}

/**
* Sorts the move list using a stable insertion sort.
*/
template<class T>
void MoveList<T>::sort() {
for (int i = 1; i < size; ++i) {
std::shared_ptr<T> entry(entries[i]);

int j = i;
while ((j > 0) && (entries[j - 1]->value < entry->value)) {
entries[j] = entries[j - 1];
--j;
}

entries[j] = entry;
}
}

/**
* Rates the moves in the list according to "Most Valuable Victim - Least Valuable Aggressor".
*/
template<class T>
void MoveList<T>::rateFromMVVLVA() {
for (int i = 0; i < size; ++i) {
int move = entries[i]->move;
int value = 0;

int piecetypeValue = PieceType::getValue(Piece::getType(Move::getOriginPiece(move)));
value += PieceType::KING_VALUE / piecetypeValue;

int target = Move::getTargetPiece(move);
if (Piece::isValid(target)) {
value += 10 * PieceType::getValue(Piece::getType(target));
}

assert(value >= (PieceType::KING_VALUE / PieceType::KING_VALUE)
&& value <= (PieceType::KING_VALUE / PieceType::PAWN_VALUE) + 10 * PieceType::QUEEN_VALUE);

entries[i]->value = value;
}
}

[0] https://github.com/fluxroot/pulse/tree/master/src/main/cpp

最佳答案

解决方案

将以模板类开头的两行移到源文件的末尾。

解释

此源代码使用显式模板实例化 (14.7.2)。只要在整个程序中只使用模板的显式实例化,就可以在源文件中(而不是在头文件中)定义模板。在这种情况下,这些将是 MoveList<MoveEntry>MoveList<RootEntry> .

但是,有一个问题:显式特化必须出现在模板定义之后 (14.7.2/4)

A declaration of a function template, a variable template, a member function or static data member of a class template, or a member function template of a class or class template shall precede an explicit instantiation of that entity. A definition of a class template, a member class of a class template, or a member class template of a class or class template shall precede an explicit instantiation of that entity unless the explicit instantiation is preceded by an explicit specialization of the entity with the same template arguments.

为什么 g++ 4.9 不强制执行这是任何人的猜测。

关于c++ - 为什么这个 c++ 代码不能在 g++ 4.8.2 中编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26983351/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com