1

I've made a class Block and a struct coords and while implementing the operators i came up with the errors:

'coords operator[](const Block&, const size_t&)' must be a nonstatic member function
'bool operator=(Block&, const Block&)' must be a nonstatic member function

I've declared these 2 in the header file of the class Block as follows:

class Block
{
  friend Block operator+(const Block&, const coords&);
  friend Block operator+(const Block&, const Block&);
  friend coords operator[](const Block&, const std::size_t&);
  friend void operator+=(Block&, const coords&);
  friend void operator+=(Block&, const Block&);
  friend bool operator=(Block&, const Block&);
//...
};

Only the operators [] and = get this error, and I'm not sure why. I've tried to change the return value and parameter types but it keeps getting the same problem. Are these two operators special? Or is there an error on my declarations? I've searched for ways to solve this problem, but couldn't find a suitable answer.

Thank you for the replies.

Lilothyn
  • 31
  • 3
  • 2
    Have a look at [this](https://stackoverflow.com/questions/4421706/operator-overloading). This whole `friend` business is most likely not the way to go. – Baum mit Augen Feb 17 '16 at 22:06
  • By the way, `bool operator=(...)` do you mean the assigment (which must be defined as a member function and should return a `Block&`) or do y mean equality operator `bool operator==(const Block&, const Block)` which is allowed to be implemented as a friend ? – Christophe Feb 17 '16 at 22:16
  • sorry, that was a mistype, it was in fact meant to be an operator==. – Lilothyn Feb 18 '16 at 23:40

4 Answers4

3

Not all operators can be overloaded using non-member functions. [] and = are two such operators. They can be overloaded only as member functions.

See http://en.cppreference.com/w/cpp/language/operators for more details.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Is there any reasoning for this restriction that you know of? – Jordan Melo Feb 17 '16 at 22:15
  • @JordanMelo, I am not that familiar with the standards development process to understand why those decisions were made. – R Sahu Feb 17 '16 at 22:22
  • 2
    @JordanMelo [Answered by member of the committee](https://stackoverflow.com/questions/1132600/why-can-some-operators-only-be-overloaded-as-member-functions-other-as-friend-f). – Baum mit Augen Feb 17 '16 at 22:25
1

Those operators cannot be declared as friends. Instead you should declare like this:

coords operator[](const std::size_t&);
bool operator=(const Block&);

Your operators are also not really following conventions. Operators += and = should be returning a Block& namely *this.

Kurt Stutsman
  • 3,994
  • 17
  • 23
0

The reason is exactly what the error message says: those two have to be non-static member functions. Get rid of the friend from in front of them and remove the first argument.

Further, operator+= is usually implemented as a member function, too, although it doesn't have to be. But if it is, it gives you an easy way to implement operator+ without making it a friend.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
0

@R Sahu's link was useful, showing that [] and = can no be declared as non-member, but it didn't really explain why. @Baum mit aguen's link cleared some other questions too. (Thanks for the information)

So, I adjusted my code to this new information as follows:

Block.h

class Block
{
public:
//...
    coords* operator[](size_t);

    Block operator=(Block);
//...
};

Block.cpp

//...
coords* Block::operator[](size_t index)
{
    if(index >= 0 && index < block.size())
        return &block.at(index);
    coords *tmp = new coords(-1, -1);
    return tmp;
}

Block Block::operator=(Block b2)
{
    block.empty();
    block.reserve(b2.block.size());
    append(b2.block);
    return *this;
}
//...

This way you can call *(*b1)[0] = c1; being Block* b1 and coords c1.

The friend modifier is useful for other types of implementations, although I only realized after that the implementation of inline had to be done in the header file, not on the cpp. Block.h

class Block
{
public:
//...
    friend std::ostream& operator<<(std::ostream&, const Block&);
    friend std::ostream& operator<<(std::ostream&, Block&);
//...
};

inline std::ostream& operator<<(std::ostream& out, const Block& b)
{
    // do something
    return out;
};

inline std::ostream& operator<<(std::ostream& out, Block& b)
{
    // do something
    return out;
};

In this case, you need to pass the "this" parameter has to be passed to the function also as these are non-member functions and should be implemented outside the class, in the header file.

I hope this helps, good coding everyone.

Lilothyn
  • 31
  • 3