0

I am trying to learn C++ and have been testing the new modules system with a toy game engine. Unfortunately, this one linking error I keep getting tells me nothing and I don't understand what I'm doing wrong. All I can really figure out is that the main function can't see the implementation of the play function, but I don't know how to fix it. I've cut my project down into the bare minimum so hopefully it's clearer to an experienced C++ programmer. Any input is appreciated, thanks.

main.cxx

import engine;

int main() {
    engine::game<engine::text_ui> my_game("My Game");
    my_game.play();
}

engine.ixx

export module engine;

export import :game;
export import :ui;

game.ixx

export module engine:game;

export import <concepts>;
export import <string>;
export import :ui;

namespace engine {
    export template<typename ui_t>
    requires std::derived_from<ui_t, ui>
    class game {
        std::string name;
        ui_t ui;
    public:
        game(std::string name) : name{name} {};
        void play() const;
    };
}

game.cxx

module engine:game;

import <concepts>;
import :ui;

namespace engine {
    template<typename ui_t>
    requires std::derived_from<ui_t, ui>
    void game<ui_t>::play() const {
        ui.notify(name + " is being played.\n");
    }
}

ui.ixx

export module engine:ui;

export import <string>;
export import <iostream>;

namespace engine {
    export class ui {
    public:
        virtual void notify(std::string text) const = 0;
    };

    export class text_ui : public ui {
        std::istream& in{std::cin};
        std::ostream& out{std::cout};
    public:
        void notify(std::string text) const override { out << text; };
    };
}

error

LNK2019 unresolved external symbol
"public: void __thiscall engine::game<class engine::text_ui>::play(void)const "
(?play@?$game@Vtext_ui@engine@@@engine@@QBEXXZ::<!engine>)
referenced in function _main
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Wungi
  • 1
  • Is this located in a single project? If not you need to add References. Linker needs to be told what it uses. – ALX23z Aug 17 '21 at 00:01
  • Templates normally need to be implemented in a header. Not sure if modules removes this. – drescherjm Aug 17 '21 at 00:26
  • Related: [https://stackoverflow.com/questions/43861385/how-are-templates-handled-in-c-module-system](https://stackoverflow.com/questions/43861385/how-are-templates-handled-in-c-module-system) – drescherjm Aug 17 '21 at 00:28
  • Yes, this is all in a single project - originally it was two separate, a static library for the engine and an executable for the game code, but after I got the error I refactored it into one executable project and it still persisted. – Wungi Aug 17 '21 at 01:01
  • Thanks for the link drescherjm, I read through it and got the sense that templates still sort of work the way I imagined, and just to make sure templates are actually supported with modules I found this [link](http://www.modernescpp.com/index.php/c-20-open-questions-to-modules) which seems to demonstrate them the way I implemented above. I also got the impression from it that with modules you want to remove includes entirely, I'd guess for consistency. – Wungi Aug 17 '21 at 01:29
  • @drescherjm: Templates defined in a module that clients need to be able to instantiate have to be in an interface unit, which behaves like a header for dependency purposes even though it can also do non-header things like define non-inline functions and variables. – Davis Herring Aug 17 '21 at 03:41
  • I've found that moving the implementation of the template class into the module interface unit works - is this how templates are supposed to be implemented? I found [this link](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) that claims the implementation of template classes aren't separated into interface and implementation, but combined into just the interface (the header), and so is this possibly the case for modules too? – Wungi Aug 17 '21 at 16:05

0 Answers0