Hi, I'm doing a low-mem implementation of a matrix, than can contain values from 0-4, this is fine for my program.
I input 4 values (each 2bit) into 1 char(8bit). I'm using bitpatterns and shifting to extract values. But this is of cause hidden from the user.

I've done everything but I'm having problem overloading the "()" operator.
I can input values, and get values, using ordinary function like

int a = obj.get(a,b); //returns value at row a, column b
obj.set(a,b,c); //insert value c at row a, column b.

But since this is c++, I want a nice consistent interface with my other matrix template class.

This means I would like to implement overloading of the "()" in such a way that

int d = obj(a,b); //set value d to the value at row a, col b
obj(a,b) = c;     // set value at row a, col b to c

Below is the interface for my class, along with my try at implementing the overloaded operators.

class snp{
private:
  unsigned char **alloc(int x, int y);
  unsigned char **m_data;
  size_t x; //number of rows.
  size_t y; // this is the number of hole used chars
  size_t offset; //offset
public:
  snp(int a,int b);
  ~snp()          {delete [] *m_data; delete [] m_data;}
  int get(int a, int b);
  void set(int a, int b, int c);
  int& operator() (uint r, uint c);
  int operator() (uint r, uint c) const;
};
//below is implementation
int& snp::operator() (uint r, uint c){
  return m_data[r][c]&0x03;//this returns 2 first bits of element at row r, col c,
}
int snp::operator() (uint r, uint c) const{
  return m_data[r][c]&0x03;
}

In this code snippet I'm just using the least 2 sig bits. When I get the syntax/idea, I will of cause implement the other bits.

Lastly my compile errors.

make
g++ testMatrix.cpp alloc.o -Wall -ansi -pedantic -ggdb
In file included from testMatrix.cpp:6:
matrix.cpp: In member function ‘int& snp::operator()(uint, uint)’:
matrix.cpp:190: error: invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘int’
make: *** [allofit] Error 1

thanks in advance

What you're asking sounds impossible to me.. What you're trying to do is return a object reference (so that you can assign to it) as well as an integer (so you can read the value).

While only slightly different to what you wanted, you could return a BitPattern object from your matrix class that contains a reference to the storage buffer, and the offset to the 2bit element of interest, such as:

class BitPatternReference{
private:
   unsigned char *buffer; // pointer to the matrix data
   
   int bitAddress;      // reference to where the bit is (for 2 bit data this is always even!)
public:
   
   // matrix class will use the following constructor:
   BitPatternReference(unsigned char *buff, int bitAddr){
      buffer = buff;
      bitAddress = bitAddr;
      }
      
   int toInt(){
      return (buffer[bitAddress>>3]>>(bitAddress&7))&3;
      }   
   
   BitPattern &operator=(int x){
      buffer[bitAddress>>3] &= ~(3<<(bitAddress&7));
      buffer[bitAddress>>3] |= (x<<(bitAddress&7));
      
      return *this;
      }
   };

So the matrix class calculates the bit offset of the bitpattern and returns a BitPatternReference object using this offset. You may then assign integer values to the BitPatternReference using e.g. mat(x, y) = 1; . The problem is you will have to convert from BitPatternReference to integer if you want to read the value, i.e. int myVal = mat(x, y).toInt(); .

You can, of course, assign a BitPatternReference to another BitPatternReference. Remember that they are just references, and don't actually contain the data (data is contained in the buffer); so if you have 2 references pointing to the same location, and change the value of one, the value of the other is affected also.

You can't obtain a reference to bit-field in C++:

A non-const reference shall not be bound to a bit-field (8.5.3).
Note: if the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly.

In your case you try to return a reference to a temporary object created for m_data[r][c]&0x03 expression value. Obviously, it's an invalid op (so compiler emits err msg).
Try to declare a new class to represent (i,j) packed element of your matrix then return this type object from overloaded non-const Matrix::operator(). I have no time to invent it now, may be later...

My suggestion is the same as dougy83's one. So dougy83 has a priority ;)!..

Thank you,
You've been very helpfull.

You can't obtain a reference to bit-field in C++:

A non-const reference shall not be bound to a bit-field (8.5.3).
Note: if the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly.

For the sake of documentation,
can you tell me where got this info.
(for my boss)

thanks

For the sake of documentation,
can you tell me where got this info.
(for my boss)

thanks

If he is citing 8.5.3 that should be the chapter/item in the C++ standard documentation...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.