1

I have tried very very hard to solve this problem. I have always been able to find my answer through Google, and this is the first time I have ever posted to a forum because of my due diligence. However, this has completely stumped me, and Google appears to be recommending the source code for gcc, which suggests to me that this problem is a rarity.

Here is my simplified code:

#include <sstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

class DJPchar{
    public:
    //General Variables
        unsigned char *word;
        int length;

    //Initialization Functions
    DJPchar();
    DJPchar(unsigned char *w, int len);
    ~DJPchar();

    DJPchar& operator+=(const DJPchar& word2);
    };

/////////////////////////////////////////////////////////////
//Initialization Functions
/////////////////////////////////////////////////////////////
DJPchar::DJPchar(){
    word = NULL;
    length = 0;
    }

DJPchar::DJPchar(unsigned char *w, int len){
    int i;

    length = len;
    word = new unsigned char[length];
    for (i=0; i<length; i++){
        word[i] = w[i];
        }
    }

DJPchar::~DJPchar(){
    delete[] word;
    }

/////////////////////////////////////////////////////////////
//Problem Function
/////////////////////////////////////////////////////////////

DJPchar& DJPchar::operator+=(const DJPchar &word2){
    unsigned char *temp;
    int i, newlength;

    temp = this->word;
    newlength = this->length + word2.length;

    this->word = new unsigned char (newlength);

    for(i=0; i<this->length; i++){
        this->word[i] = temp[i];
        }
    for(i=this->length; i<newlength; i++){
        this->word[i] = word2.word[i-this->length];
        }

    this->length = newlength;
    delete[] temp;

    return *this;
    }

int main(){
    unsigned char a;
    unsigned char b[7];

    a = 'b';
    b[0] = 'b';
        b[1] = 'a';
        b[2] = 't';
        b[3] = '\n';
        b[4] = 200;
        b[5] = 'n';
        b[6] = '!';

    DJPchar *c_a = new DJPchar(&a, 1);
    DJPchar *c_b = new DJPchar(b, 7);

    c_a += c_b; //Error Line

    return 0;
}

I created a large list of comparison functions (I'm trying to recreate the string class for unsigned characters, if someone knows of something that exists for this, that would be swell!) and they all worked perfectly, but the error I've been getting for this is:

Broken.cpp:86: error: invalid operands of types ‘DJPchar*’ and ‘DJPchar*’ to binary ‘operator+’
Broken.cpp:86: error:   in evaluation of ‘operator+=(class DJPchar*, class DJPchar*)’

and I have been going nuts, looking for if I used a '+' inside the function I was trying to use as the basis for the +, and then changing all kinds of pointers and whatnot, and putting it outside the class and inside the class.

Tomorrow, I may refer to rule #1 of the General rules of Operator overloading but today I've spent 6 hours on something that was supposed to take four minutes to verify it was working and move forward... I am a very sad panda.

Community
  • 1
  • 1
Daniel Peirano
  • 514
  • 5
  • 12
  • Oh God Oh God Oh God... Completely solved this within fourteen seconds of posting... As it was screaming for, it wanted me to post c_a += c_b as *c_a += *c_b I don't fully understand why it should be this way, but it was clear as day as soon as I looked at that error one more time... I will leave this up as a testament to my idiocy (no joke on the six hours spent on this, should have spent six hours and 15 sec...) and as a warning should anyone else stumble upon this error with pointer math 101... – Daniel Peirano Sep 16 '11 at 10:42
  • Oh, that's probably true. This was part of a much larger test bench for my classes, so the DJPchar objects are being dynamically allocated and added onto other objects. That part of the code could have been removed. – Daniel Peirano Sep 16 '11 at 10:47
  • 1
    "recreate the string class for unsigned characters" - so essentially you're looking for `std::basic_string` ? – MSalters Sep 16 '11 at 10:49
  • Wow. Thank everyone for posting responses so quickly! I was assuming that this would be an overnight fix, but thank you all so much! – Daniel Peirano Sep 16 '11 at 10:50
  • It usually helps *reading* the error messages (rather than just *identifying* that there is an error and the line). As to the speed of answers in SO (not your 15s, but the 3m that took Oli to answer correctly) I agree that it is amazing. – David Rodríguez - dribeas Sep 16 '11 at 10:54

3 Answers3

4

Operator overloads must have at least one argument that is a user-defined type. Your code is:

DJPchar *c_a = new DJPchar(&a, 1);
DJPchar *c_b = new DJPchar(b, 7);

c_a += c_b; //Error Line

Both c_a and c_b are pointers, which are not user-defined types.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • Mmm. no +1 yet because (a) you don't show how to fix it (b) you don't address the 'why it should be this way' part of the question. This answer could easily be way more helpful. – sehe Sep 16 '11 at 10:52
  • @sehe: Fair enough. But the fix ought to be immediately obvious. The "why" isn't really relevant to the question (and note that pointers aren't the only primitive types that the operator overloading rules apply to). – Oliver Charlesworth Sep 16 '11 at 10:53
  • The OP searched for 6 hours. He was about to 'read the source for gcc'. I can't agree it ought to be obvious. I do think the OP (a) ought to get some sleep, or (b) read a good book on C++ – sehe Sep 16 '11 at 10:55
1

I got the similar error: invalid operands of types ‘int64_t {aka long int}’ and ‘’ to binary ‘operator*’ but for a different reason than OP.

For me I was trying to multiply a value by "index" which was declared further down in the function.

Sadly, it seemed to be complaining about parameters to the function from before the actual bad part. Removing the "* index" from

int64_t x = 10, y = 10;
someFunction(&x, &y, size * index);
...
int index = 1;

fixed the problem. Unhelpful error message I guess.

Dirk Bester
  • 1,791
  • 19
  • 21
1

The fix should be:

(*c_a) += *c_b;

Operators in C++ are not 'lifted' (like in functional languages, like e.g. Haskell; C# has the notion of lifted operator for Nullable types)

Note @Daniel: This answer references the answer to your question ("why it should be this way"): C++ doesn't do automatic lifted operators for pointers. I guess this is probably mainly because C++ wants to stay C-compatible with respect to pointer arithmetic instead.

sehe
  • 374,641
  • 47
  • 450
  • 633