misty
misty

Reputation: 123

Error when using overloaded operator () C++

Here is a C++ code, it is simple, but I get error which I don't understand.
I don't know how else to use overloaded operator (), but the way I did.
Program should do the following.

Type your word: Programming
n: 5
P
Pr
Pro
Prog
Progr

Error I get:

no match for 'operator<<' in 'std::cout << Word::operator()(int)(n)'

Word.h

#ifndef WORD_H
#define WORD_H


class Word
            {
            private:
                    char *str;
            public:
                    Word();
                    ~Word();
                    Word operator()(int); //overloading operator ()
                    friend std::ostream& operator<<(std::ostream&,Word&);
                    friend std::istream& operator>>(std::istream&,Word&);
            };

#endif

Word.cpp

#include <iostream>
#include <cstring>
#include "Word.h"

Word::Word()
    {
    str=new char[100];
    }

Word::~Word()
    {
    delete[] str;
    }


Word Word::operator()(int d)  //overloading operator ()
    {
    Word pom;
    strncpy(pom.str,str,d);
    return pom;
    }


std::ostream& operator<<(std::ostream& out,Word& s)
    {    
    out<<s.str; return out;
    }


std::istream& operator>>(std::istream& in,Word& s)
    {
    in>>s.str; return in;
    }

main.cpp

#include<iostream>
#include "Word.h"


int main()
{
   Word r;
   std::cout<<"Type your word: "; 
   std::cin>>r;

   int n;
   std::cout<<"n:"; 
   std::cin>>n;

   for (int i=1; i<=n; i++) std::cout << r(i) << std::endl; //error when using r(i)
}

Upvotes: 3

Views: 195

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

When you do this

cout << r(i);

the compiler does the following:

  • Creates a temporary variable of type Word
  • Calls operator(int), and captures its result
  • Stores the result in a temporary object
  • Passes the temporary object to operator <<

Since you have no access to the temporary object, the compiler disallows non-constant access to it. That is why you get the error: you are trying to pass an object that is implicitly constant to a parameter that takes a non-constant reference.

To fix this, change the signature of your operator<< to the canonical one, i.e. taking a const reference for the Word& parameter:

friend std::ostream& operator<<(std::ostream&, const Word&);
//                                             ^^^^^

Upvotes: 2

pmr
pmr

Reputation: 59811

The problem is the signature of

std::ostream& operator<<(std::ostream& out,Word& s);

This accepts a Word by reference.

Word operator()(int);

returns a Word by value. In the expression

cout << r(i);

you end up trying to bind a temporary value to a reference, which is forbidden by the language. Only a reference to const can bind to a temporary value. Change your operator<< signature (in the declaration and definition) to:

std::ostream& operator<<(std::ostream& out, const Word& s);

and it should work. This is also a sensible choice, since operator<< should not change the Word argument.

Upvotes: 4

Related Questions