Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

declaring field as const invokes " function operator=(const memAddress &) cannot be referenced -- it is a deleted function"

Tags:

c++

oop

I've got a struct to store and manipulate memory address. I decided to change one of the fields from int to const int to ensure it's read-only and all of a sudden the operator-() that I defined complains with the following message:

function "memAddress::operator=(const memAddress &)" (declared implicitly) cannot be referenced -- it is a deleted function

Here's the code,

struct memAddress
{
    // memory location variables
    int die = 0;
    int plane = 0;
    int page = 0;
    int column = 0;
    int block = _BLOCK_STARTING_ADDRESS;

    memAddress() {}

    memAddress(const memAddress &m)
    {
        die = m.die;
        plane = m.plane;
        page = m.page;
        column = m.column;
        block = m.block;
    }

    bool operator<(const memAddress &m)
    {
        if (die > m.die)
            return false;
        else if (die == m.die)
        {
            if (plane > m.plane)
                return false;
            else if (plane == m.plane)
            {
                if (block > m.block)
                    return false;
                else if (block == m.block)
                {
                    if (page > m.page)
                        return false;
                    else if (page == m.page)
                    {
                        if (column >= m.column)
                            return false;
                        else
                            return true;
                    }
                    else
                        return true;
                }
                else
                    return true;
            }
            else
                return true;
        }
        else
            return true;

    }

    bool operator==(const memAddress &m)
    {
        if (die == m.die &&
            plane == m.plane &&
            block == m.block &&
            page == m.page &&
            column == m.column)
        {
            return true;
        }

        return false;
    }

    bool operator<=(const memAddress &m)
    {
        if ((*this < m) || (*this == m))
            return true;

        return false;
    }

    bool operator>(const memAddress &m)
    {
        if (!(*this <= m))
            return true;

        return false;
    }

    bool operator>=(const memAddress &m)
    {
        if ((*this > m) || (*this == m))
            return true;

        return false;
    }

    memAddress operator-(const memAddress &m)
    {
        memAddress diff, a1, a2;

        if (*this < m)
        {
            a2 = m; // **error** 
            a1 = *this; // **error**
        }
        else
        {
            a2 = *this; // **error**
            a1 = m; // **error**
        }

        diff.die = a2.die - a1.die;
        diff.plane = a2.plane - a1.plane;
        diff.block = a2.block - a1.block;
        diff.page = a2.page - a1.page;
        diff.column = a2.column - a1.column;

        return diff;

    }

private:
    const int _BLOCK_STARTING_ADDRESS = 2; // **modifier added here**

};

I'm clueless as why this is happening - the code works fine if the modifier is removed.

Why would changing the field modifier to const lead to this behavior? How can I go around it?

like image 384
scriptsNgiggles Avatar asked Jan 01 '23 18:01

scriptsNgiggles


2 Answers

Your use of all caps (as well as using it to initialize block) indicates you intend _BLOCK_STARTING_ADDRESS to be a class constant for all instances.

So first and foremost, make it static

static const int _BLOCK_STARTING_ADDRESS = 2;

Why? Because otherwise it is a data member of every instance. Meaning every instance has a little piece of it that must be const, and you can't assign by default to that const bit. The compiler can't generate a default assignment operator for you for that reason.

Also, as a side not. Names beginning with _[A-Z] are reserved to the C++ implementation for any use. To avoid the possibility of nasal demons, I suggest you change your naming scheme for it. Perhaps even to one with less shouting?

like image 76
StoryTeller - Unslander Monica Avatar answered Jan 04 '23 09:01

StoryTeller - Unslander Monica


Since you have a non-static data member of const non-class type (const int _BLOCK_STARTING_ADDRESS), the default assignment operator is deleted.

Making the member static would generate the default assignment operator.

The CPP draft (N4713) states this about assignment operator:

15.8.2 Copy/move assignment operator
...
7. A defaulted copy/move assignment operator for class X is defined as deleted if X has:
(7.1) — a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
(7.2) — a non-static data member of const non-class type (or array thereof), or
(7.3) — a non-static data member of reference type, or
(7.4) — a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution (16.3), as applied to find M’s corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.

like image 29
P.W Avatar answered Jan 04 '23 09:01

P.W