C++ 模板,链接阶段未定义引用错误
C++ template, linking stage undefined reference error
我正在使用 C++ 模板并遇到以下问题。
我尝试在classImplM
中使用classImplG
的方法func
,但是链接器报错
user:/home/test/build# make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cc.o
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/main.cc.o:(.data.rel.ro._ZTV9GatheringI9ImplState9ImplRouteE[_ZTV9GatheringI9ImplState9ImplRouteE]+0x10): undefined reference to `Gathering<ImplState, ImplRoute>::gather(ImplState const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:84: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
# CMakeLists.txt
ADD_EXECUTABLE(main
main.cc
)
// mctsimpl.hpp
#include <vector>
class State {
};
template <class T>
class Action {
void execute(T&);
};
template <class A>
class Route {
public:
std::vector<A> actions;
A getAction();
};
template <class T, class R>
class Gathering {
public:
virtual R gather(const T&);
};
// Actually this is a MCTS implementation
// But those search methods are omitted here
// I just need to collect some actions
template<class T, class A, class R>
class MCTS {
public:
MCTS(T& rootData, Gathering<T, R>* gathering) :
state(rootData),
gathering(gathering) {
}
R gather() {
return gathering->gather(state);
}
private:
Gathering<T, R>* gathering;
T& state;
};
// mctslib.hpp
#include "mctsimpl.hpp"
class ImplAction;
class ImplRoute;
class ImplState : public State {
public:
ImplState() :
i(0) {
}
int i;
std::vector<ImplAction> actions;
void execute(int i);
ImplRoute gather() const;
};
class ImplAction : Action<ImplState> {
public:
ImplAction(int i) :
i(i) {
};
int i;
void execute(ImplState& state) {
state.execute(i);
}
};
class ImplRoute : public Route<ImplAction>{
public:
ImplRoute(std::vector<ImplAction> actions) :
actions(actions) {
}
ImplAction getAction() {
return actions[0];
}
std::vector<ImplAction> actions;
};
class ImplGathering : public Gathering<ImplState, ImplRoute>{
public:
ImplGathering() {}
ImplRoute gather(const ImplState& s) override {
return s.gather();
}
};
using ImplMCTS = MCTS<ImplState, ImplAction, ImplRoute>;
// mcts.hpp
#include "mctslib.hpp"
void ImplState::execute(int i) {
actions.push_back(ImplAction(i));
this->i = i;
}
ImplRoute ImplState::gather() const {
return ImplRoute(actions);
}
// main.cc
#include "mcts.hpp"
int main() {
ImplState state;
ImplGathering* gathering = new ImplGathering();
ImplMCTS mcts(state, gathering);
ImplAction action(1);
action.execute(state);
action.execute(state);
action.execute(state);
// Use here
mcts.gather();
}
现在我提供我的简化代码并添加链接错误。
将您的 class 抽象化(通过添加 = 0
),例如:
template <class T, class R>
class Gathering {
public:
virtual R gather(const T&) = 0;
};
我正在使用 C++ 模板并遇到以下问题。
我尝试在classImplM
中使用classImplG
的方法func
,但是链接器报错
user:/home/test/build# make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cc.o
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/main.cc.o:(.data.rel.ro._ZTV9GatheringI9ImplState9ImplRouteE[_ZTV9GatheringI9ImplState9ImplRouteE]+0x10): undefined reference to `Gathering<ImplState, ImplRoute>::gather(ImplState const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:84: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
# CMakeLists.txt
ADD_EXECUTABLE(main
main.cc
)
// mctsimpl.hpp
#include <vector>
class State {
};
template <class T>
class Action {
void execute(T&);
};
template <class A>
class Route {
public:
std::vector<A> actions;
A getAction();
};
template <class T, class R>
class Gathering {
public:
virtual R gather(const T&);
};
// Actually this is a MCTS implementation
// But those search methods are omitted here
// I just need to collect some actions
template<class T, class A, class R>
class MCTS {
public:
MCTS(T& rootData, Gathering<T, R>* gathering) :
state(rootData),
gathering(gathering) {
}
R gather() {
return gathering->gather(state);
}
private:
Gathering<T, R>* gathering;
T& state;
};
// mctslib.hpp
#include "mctsimpl.hpp"
class ImplAction;
class ImplRoute;
class ImplState : public State {
public:
ImplState() :
i(0) {
}
int i;
std::vector<ImplAction> actions;
void execute(int i);
ImplRoute gather() const;
};
class ImplAction : Action<ImplState> {
public:
ImplAction(int i) :
i(i) {
};
int i;
void execute(ImplState& state) {
state.execute(i);
}
};
class ImplRoute : public Route<ImplAction>{
public:
ImplRoute(std::vector<ImplAction> actions) :
actions(actions) {
}
ImplAction getAction() {
return actions[0];
}
std::vector<ImplAction> actions;
};
class ImplGathering : public Gathering<ImplState, ImplRoute>{
public:
ImplGathering() {}
ImplRoute gather(const ImplState& s) override {
return s.gather();
}
};
using ImplMCTS = MCTS<ImplState, ImplAction, ImplRoute>;
// mcts.hpp
#include "mctslib.hpp"
void ImplState::execute(int i) {
actions.push_back(ImplAction(i));
this->i = i;
}
ImplRoute ImplState::gather() const {
return ImplRoute(actions);
}
// main.cc
#include "mcts.hpp"
int main() {
ImplState state;
ImplGathering* gathering = new ImplGathering();
ImplMCTS mcts(state, gathering);
ImplAction action(1);
action.execute(state);
action.execute(state);
action.execute(state);
// Use here
mcts.gather();
}
现在我提供我的简化代码并添加链接错误。
将您的 class 抽象化(通过添加 = 0
),例如:
template <class T, class R>
class Gathering {
public:
virtual R gather(const T&) = 0;
};