I have a class "Ram" with a template parameter that specifies its bank size. e.g.
ram.hpp
#include <vector>
#include <array>
#include <cstdint>
#include <iostream>
template <uint16_t bank_sz>
class Ram
{
public:
uint8_t read(uint8_t bank, uint16_t adr) const;
void write(uint8_t b, uint8_t bank, uint16_t adr);
void resize(uint8_t nbanks);
private:
std::vector<std::array<uint8_t, bank_sz>> data_;
};
// explicit template instantiations
template class Ram<0x2000>;
template class Ram<0x1000>;
using Work_ram = Ram<0x1000>;
using Video_ram = Ram<0x2000>;
and the implementation:
ram.cpp
template <uint16_t bank_sz>
uint8_t Ram<bank_sz>::read(uint8_t bank, uint16_t adr) const
{
if (bank > data_.size() || adr > bank_sz)
throw std::out_of_range {"Invalid RAM address"};
return data_[bank][adr];
}
template <uint16_t bank_sz>
void Ram<bank_sz>::write(uint8_t b, uint8_t bank, uint16_t adr)
{
if (bank > data_.size() || adr > bank_sz)
throw std::out_of_range {"Invalid RAM address"};
data_[bank][adr] = b;
}
template <uint16_t bank_sz>
void Ram<bank_sz>::resize(uint8_t nbanks)
{
data_.resize(nbanks);
}
When I try to use it, for example
#include "ram.hpp"
int main()
{
Video_ram r {};
r.resize(1);
r.write(0xff, 0, 0);
std::cout << r.read(0, 0);
return 0;
}
I get the warning: "instantiation of function Ram<8192> required here, but no definition is available." Everything compiles and works as expected, though. Could this be because I seperated the declaration and implementation of the Ram class into different files? I thought it would be okay because of the explicit instantiation at the end of "ram.hpp".