C++ templates behaving as if they're not there?

Discussion in 'Computer Programming, Emulation, and Game Modding' started by StackMasher, Apr 18, 2017.

  1. StackMasher
    OP

    StackMasher GBAtemp Regular

    Member
    3
    Nov 29, 2016
    So here's my code:
    Code:
    //cartridge.h
    #ifndef CARTRIDGE_INCLUDED
    #define CARTRIDGE_INCLUDED
    
    #include <cstdint>
    #include <cstddef>
    #include "type.h"
    #include "../types.h"
    #include "mbc.h"
    #include "../util/smartArray.h"
    
    namespace Gameboy {
        class Cartridge {
            public:
                constexpr static Address header = 0x100;
                constexpr static unsigned int romBankSize = 0x4000;
                constexpr static unsigned int ramBankSize = 0x2000;
    
            protected:
                Util::SmartArray<Byte*> romBanks;
                Util::SmartArray<Byte*> ramBanks;
    
                unsigned int romBank0 = 0;
                unsigned int romBank1 = 1;
                unsigned int ramBank = 0;
    
                int romSize = 0;
                int ramSize = 0;
    
                MBC mbc;
                const char* name = NULL;
                bool nameCopied = false;
                CartType type;
    
            public:
                void clear();
                void load(const char* romname);
                void update();
    
                template <typename type> type read(Address address);
                template <typename type> void write(Address address, type toWrite);
                const char* getName();
    
                Cartridge(const char* romname = NULL);
                ~Cartridge();
        };
    }
    
    #include "cartridgeIO.h"
    
    #endif
    
    //cartridgeIO.h
    template <typename type> type Gameboy::Cartridge::read(Address address) {
        if (address <= 0x3FFF) {
            return *((type*)romBanks[romBank0][address]);
        }
        else if (address <= 0x7FFF) {
            return *((type*)romBanks[romBank1][address-0x3FFF]);
        }
        else if (address >= 0xA000 && address <= 0xBFFF && mbc.getType()!=2) {
            return *((type*)ramBanks[ramBank][address-0x9FFF]);
        }
        else {
            return mbc.read<type>(address);
        }
    }
    
    template <typename type> void Gameboy::Cartridge::write(Address address, type toWrite) {
        if (address >= 0xA000 && address <= 0xBFFF && mbc.getType()!=2) {
            *((type*)&ramBanks[ramBank][address-0x9FFF]) = toWrite;
        }
        else {
            mbc.write<type>(address, toWrite);
        }
    }
    And here's the errors the compiler produces:
    Code:
    g++-6 -g -c gb.cpp -o .build/gb.o
    In file included from cartridge/cartridge.h:48:0,
                     from gb.h:6,
                     from gb.cpp:1:
    cartridge/cartridgeIO.h: In member function ‘type Gameboy::Cartridge::read(Gameboy::Address)’:
    cartridge/cartridgeIO.h:12:29: error: expected primary-expression before ‘>’ token
             return mbc.read<type>(address);
                                 ^
    cartridge/cartridgeIO.h: At global scope:
    cartridge/cartridgeIO.h:16:74: error: ‘type’ is not a type
     template <typename type> void Gameboy::Cartridge::write(Address address, type toWrite) {
                                                                              ^~~~
    cartridge/cartridgeIO.h:16:31: error: prototype for ‘void Gameboy::Cartridge::write(Gameboy::Address, int)’ does not match any in class ‘Gameboy::Cartridge’
     template <typename type> void Gameboy::Cartridge::write(Address address, type toWrite) {
                                   ^~~~~~~
    In file included from gb.h:6:0,
                     from gb.cpp:1:
    cartridge/cartridge.h:40:43: error: candidate is: template<class type> void Gameboy::Cartridge::write(Gameboy::Address, type)
                 template <typename type> void write(Address address, type toWrite);
                                               ^~~~~
    
    So basically it acts as if the templates are not there before the definition, and I can't figure out why
     
  2. bailli

    bailli GBAtemp Regular

    Member
    6
    Oct 16, 2006
    Gambia, The
    Hm not really sure...

    Do you know that header files need to contain the full template's code and not only the forward declaration?

    EDIT: Also: Maybe you are not referencing the correct namespace(s)?
     
    Last edited by bailli, Apr 18, 2017
  3. StackMasher
    OP

    StackMasher GBAtemp Regular

    Member
    3
    Nov 29, 2016
    I include cartridgeIO.h at the bottom of cartridge.h
     
  4. bailli

    bailli GBAtemp Regular

    Member
    6
    Oct 16, 2006
    Gambia, The
    The first error is about not finding mbc.read - did you check that this template is accessible?

    Also see my above edit. Did you check namespaces? There is an error "‘type’ is not a type" <- is it actually "GameBoy::type"?
    (Namespaces sometimes confuse me - also they are generally a good idea...)
     
  5. StackMasher
    OP

    StackMasher GBAtemp Regular

    Member
    3
    Nov 29, 2016
    It's because I have a member variable called "type" in Gameboy::Cartridge aswell
    I also haven't implemented mbc.read<type> and mbc.write<type> yet
    Fixed now :)
     
Quick Reply
Draft saved Draft deleted
Loading...