Ian Vaughan
Ian Vaughan

Reputation: 21321

template class with overridden operators

I want to add a operator override to perform assignments/__set__s inline.

Template :-

class CBase {
    public :
        static void SetupVmeInterface(CVmeInterface *in);

    protected :
        static CVmeInterface *pVmeInterface;
};


template <class T> class TCVmeAccess : public CBase {
    public:
        TCVmeAccess(int address);

        T get()
        {
            unsigned long temp = pVmeInterface->ReadAddress(Address);
            T ret = *reinterpret_cast<T*>(&temp);
            return ret;
        };

        T *operator->();
        unsigned long asLong();

        bool set(T data)
        {
            unsigned long write_data = *reinterpret_cast<unsigned long*>(&data);
            return pVmeInterface->WriteAddress(Address, write_data);
        };

        // void operator->(T);
        void operator=(T data)
        { set(data); }

    private :
        int Address;
};

A struct that will be used in the template :-

typedef struct
{
    int a: 1; // 0
    int b: 1; // 1
    int c: 1; // 2
    int d: 1; // 3
    int NotUsed : 28; // 31-4
} _HVPSUControl;

Code body :-

TCVmeAccess<_HVPSUControl> HVPSUControl(constHVPSUControlBlock);
_HVPSUControl hvpsu = HVPSUControl.get(); // Yep, good, but not as nice as...
int a = HVPSUControl2.get().OperationalRequestPort; // yep, also good, but...
int b = HVPSUControl->a; // works, and is all go so far

HVPSUControl.set(hvpsu); // works, but need _HVPSUControl type
HVPSUControl = hvpsu;    // also works, as operator = is used, but still need type

// this line does not work!
// as the = assignment is redirected into a copy of the struct, not the template
HVPSUControl->a = 1; // this line

So, is there a way to get this line above to work?

Edit: As in, I want "this line" to perform as a "set" as does in the template class.

Edit: 1. Assign a value directly in-line to a member of the struct that the template is formed of.
2. Cause that assignment to go though a template accessor.

So that I dont have to do this on assignments :-

// HVPSUControl is predefined and used many times.
_HVPSUControl hvpsu;
hvpsu.a = 1;
HVPSUControl.set(hvpsu);

I want to do

HVPSUControl.a = 1; // or 
HVPSUControl->a = 1; // or ?

As gets work on line :

if (HVPSUControl->a)

Upvotes: 0

Views: 237

Answers (2)

Gunther Piez
Gunther Piez

Reputation: 30439

Instead of overwriting the "->" and the "=" operator, you could derive from the template struct.

template <class T> class TCVmeAccess : public CBase, public T {
    public:
        TCVmeAccess(int address);

        T get();
        // T *operator->();
        unsigned long asLong();

        bool set(T);
        // void operator->(T);
        // void operator=(T);

    private :
        int Address;
};

HVPSUControl.a = 1; // and use this for setting a bitfield.

Edit: If you want to use an custom assignment operator, you should declare it in HVPSUControl, or a even a base class of it, if you have more of this control-like structures.

struct _HVPSUControl
{
    int a: 1; // 0
    int b: 1; // 1
    int c: 1; // 2
    int d: 1; // 3
    int NotUsed : 28; // 31-4
    void operator = (int x);
};

or

struct _HVPSUBase {
    void operator = (int x);
}
struct _HVPSUControl: public _HVPSUBase
{
    int a: 1; // 0
    int b: 1; // 1
    int c: 1; // 2
    int d: 1; // 3
    int NotUsed : 28; // 31-4
};

Upvotes: 1

Sebastian
Sebastian

Reputation: 4950

You can't get this line to work any other way. You call TCVmeAccess::operator-> which returns a _HVPSUControl* and then you access _HVPSUControl*::a.

Or do you want to assign integer 1 to the complete _HVPSUControl struct?

template <class T> class TCVmeAccess : public CBase {
public:
    // ...

    void operator=(T data) { set(data); }
    void operator=(int n) { operator=(T(n)); }

    // ...
};


typedef struct
{
    _HVPSUControl(int n) {
       *this = reinterpret_cast<_HVPSUControl>(n);
    }

    int a: 1; // 0
    int b: 1; // 1
    int c: 1; // 2
    int d: 1; // 3
    int NotUsed : 28; // 31-4
} _HVPSUControl;

and then do

HVPSUControl = 1;

Upvotes: 0

Related Questions