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;
};