3

Problem:

Error: The "&" operator can only be applied to a variable or other l-value.

What I've tried:

  • dynamic_cast<char*>(e)
  • reinterpret_cast<char*>(e)
  • static_cast<char*>(e)
  • (char*) e

What I'm trying to do:

  • Write the array e.data (private) to a binary file.

Notes:

  • e.getSize() returns number of elements in array
  • e[] returns Employee object.

Code:

fstream fout;
fout.open(filename.c_str(), ios::out|ios::binary);
if(fout.good())
{
    for(int i=0;i<e.getSize();i++)
    {
        fout.write((char*)&e[i], sizeof(e[i]));
    }
}
fout.close();

Employee.h

class Employee {
    friend std::ostream& operator<<(std::ostream&, const Employee &);
    private:
        int id;
        char name[50];
        char address[100];
        char phone[20];
        char department[100];
        int salary;
    public:
        Employee();
        ~Employee();
        Employee(int,char[],char[],char[],char[],int);
        bool operator==(Employee&);
};

I'm lost at what to do, from what I remember fout.write((char*)&e[i], sizeof(e[i])); is how to write to binary files.

Edit: e is declared like so: MYLIB::Bucket<Employee> e;

template <class T>
class Bucket {
    private:
        T* bkt;
        int size;
        int capacity;
        static const int stepsize = 10;

    public:
        Bucket();
        ~Bucket();

        void push_back(const T&);
        T operator[](int);
        int getSize();
        int getCapacity();
};

Edit 2: fout.write(reinterpret_cast<char*>(e[i]), sizeof(e[i])); gives me line 122: Error: Using reinterpret_cast to convert from ? to char* not allowed. (Line 122 is the line just quoted)

Edit 3:

tempemp = e[i];
fout.write((char*)(&tempemp), sizeof(e[i]));

Compiles but gives a segmentation fault, I'll investigate why. Compiles, the segmentation fault looks unrelated.

John Smith
  • 63
  • 1
  • 4

2 Answers2

4
 MYLIB::Bucket<Employee> e;

this seems to be a container. e[i] gives you an Employee by value. you need to get this object's address using &e[i] but you can'd do that since it's an r-value so you need to copy it to a non r-value:

Employee copye = e[i];
fout.write((char*)&copye, sizeof(e[i]));

Should work.

On a side note, this all looks like terrible code and I don't envy whoever needs to maintain or read it. A few points:

  • you should not be using the binary format of the in-memory object as your serialization format. Use a proper serialization format like protobuf or xml or json
  • Why pull your own strange containers when you can use std::vector std::list ? re-inventing the wheel is always bad
  • returning an element by value from a container creates copies which degrade performance.
shoosh
  • 76,898
  • 55
  • 205
  • 325
2

I think that

T operator[](int);

is returning a temporary object that must be bound to something before an address can be taken

const Employee& emp = e[i];
fout.write((char*)&emp, sizeof(emp));

might work, assuming this answer is correct that taking a reference extends the life of a temporary object

An alternative might be to return a reference to the object, which would remove the creation of temporary objects

const T& operator[](int);
Community
  • 1
  • 1
David Sykes
  • 48,469
  • 17
  • 71
  • 80