-1

Im having troubles invoking a function by using function pointer declared as a member of a struct inside of a class In the master.cpp:

#include "headers/master.hh"
#include "headers/bus.hh"
#include <memory.h>
#include <stdint.h>
#include <iostream>

int main()
{
    int size = 4;
    Bus prova;
    int su = (prova.BIOS_ROM.*read_ptr)(prova.BIOS_ROM, size);
    printf("%p\n", (void *)prova.BIOS_ROM.read_ptr);
}

In the bus.hh file:

#ifndef BUS_H
#define BUS_H

#include <stdint.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <array>

class Bus
{
public:
    template <typename T> // T is the bit width of the bus
    struct bus_t
    {
        T bitfield;
        char r_perm : 3; // 8/16/32 bit read
        char w_perm : 3; // 8/16/32 bit read

        T (Bus::*read_ptr)(struct bus_t<T> bus, int size);
        void (Bus::*write_ptr)(struct bus_t<T> bus, int size, T data);
    };

    template <typename T>
    T read(struct bus_t<T> bus, int size);

    template <typename T>
    void write(struct bus_t<T> bus, int size, T data);


    struct bus_t<uint32_t> BIOS_ROM;

public:
    Bus();
    ~Bus();
};

#include "bus.tpp"
#endif /* !BUS_H */

bus.tpp file:

#pragma once
template <typename T>
T Bus::read(struct bus_t<T> bus, int size)
{
    printf("Bus.bitfield is %d\n", bus.bitfield);
    printf("Size is %d\n", size);
    return bus.bitfield >> size; // 10 0001 = 33
}

template uint32_t Bus::read(struct bus_t<uint32_t> bus, int size);

template <typename T>
void Bus::write(struct bus_t<T> bus, int size, T data)
{
    //read<uint32_t>(bus, size);
    bus.bitfield = data;
}

And in the bus.cpp file:

#include "headers/bus.hh"

Bus::Bus()
{
    BIOS_ROM.bitfield = 0;
    BIOS_ROM.r_perm = 7;
    BIOS_ROM.read_ptr = &Bus::read<uint32_t>;
    BIOS_ROM.write_ptr = &Bus::write<uint32_t>;

}

Bus::~Bus()
{
}

I really cant find where the problem lies. Im new to C++(Ive been mostly programming in java/c) so I dont exactly know how generics syntax work in C++

I've also tried taking a look at this thread Why can templates only be implemented in the header file? but I didnt actually understand what should I fix in my code in order to make it run

EDIT: While compiling with g++, it gives me the following error:

master.cpp:11:31: error: ‘read_ptr’ was not declared in this scope
   11 |     int su = (prova.BIOS_ROM.*read_ptr)(prova.BIOS_ROM, size);
Dennis
  • 21
  • 2
  • 1
    Are you saying this code produces some error message? – Drew Dormann Feb 15 '22 at 16:57
  • Please describe the problem you are having. It isn't what isn't working or how it isn't working. Is it failing to compile? Is it crashing? What error messages do you see? "It doesn't work" is not a useful description of the problem, we can't know what that means. – François Andrieux Feb 15 '22 at 16:59
  • What is `BIOS_ROM`? You want `(prova.BIOS_ROM.*prova.BIOS_ROM.read_ptr)(...)`? – KamilCuk Feb 15 '22 at 17:00
  • It produces a compilation error stating that read_ptr is undefined – Dennis Feb 15 '22 at 17:00
  • 1
    @Dennis There is likely not enough information to identify the cause of the problem. Please read about and try to provide a [MCVE]. – François Andrieux Feb 15 '22 at 17:01
  • I usually use `std::bind(&Class::method, instancePtr, std::placeholders::_1)` it ends like `instancePtr->method(someParam);` - it's easier than messing with it directly – KIIV Feb 15 '22 at 17:03

1 Answers1

1

I have no idea why this was repeatedly closed as a duplicate to the C++ template-header question. You seem to be misunderstanding pointer-to-member syntax. I think what you're seeking is:

int su = (prova.*prova.BIOS_ROM.read_ptr)(prova.BIOS_ROM, size);

The general syntax for concrete objects or references to fire members there in is

(obj.*memfnptr)(arguments...)

If using a pointer-to-object calling a pointer-to-member, then the syntax becomes:

(ptr->*memfnptr)(arguments...)

You can read more about it here: Member access operators.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141