In the following snippet of code the compiler (g++ on RH 4) does not see my overloaded operator. I cannot figure out why.

Error:
parse_opra.cpp: In function `void parseFile(std::istream&)':
parse_opra.cpp:19: error: no match for 'operator>>' in 'in >> rec'
note: candidates are: std::basic_istream<_CharT,......
.....
opra_record.h:35: note: std::istream& operator>>(std::istream&, Opra_record&)

I am especially confused by the last candidate (above) as that is what I am looking for...??

Thanks in advance for any clarification.

Steve

//opra_record.h
 
class Opra_record {
    friend std::ifstream& operator>>(std::ifstream&, Opra_record&);
private:
    std::vector<std::string> stringData;
    std::vector<long> numericData;
    std::string temp;
 
public:
    typedef std::vector<std::string>::size_type size_type;
    Opra_record();
    Opra_record(const Opra_record&);
    ~Opra_record();
    Opra_record(const std::vector<std::string>&);
    size_type size() const;
    std::string& operator[] (size_type i);
    const std::string& operator[] (size_type i) const;
 
};
 
std::ifstream& operator>>(std::ifstream&, Opra_record&);
//parse_opra.cpp
 
#include "opra_record.h"
 
void parseFile(ifstream& in)
{
    string tmp;
    Opra_record* rec = new Opra_record;
    while(!in.eof()) {
        in >> rec;                 ///***************here 
    }
}
 
int main(int argc, char** argv){
    if (argc < 2)
        return(EXIT_FAILURE);
    ifstream in(argv[1]);
    if(!in)
        return(EXIT_FAILURE);
    parseFile(in);
}

Did you forget to include <fstream> ?

this compiles without error or warnings using my compiler which is not g++.

#include <fstream>
#include <vector>
using namespace std;

class Opra_record {
    friend std::ifstream& operator>>(std::ifstream&, Opra_record&);
private:
    std::vector<std::string> stringData;
    std::vector<long> numericData;
    std::string temp;
 
public:
    typedef std::vector<std::string>::size_type size_type;
    Opra_record() {}
    Opra_record(const Opra_record&);
    ~Opra_record() {}
    Opra_record(const std::vector<std::string>&);
    size_type size() const;
    std::string& operator[] (size_type i);
    const std::string& operator[] (size_type i) const;
 
};
 
std::ifstream& operator>>(std::ifstream& in, Opra_record& r)
{
	return in;
}
 
void parseFile(ifstream& in)
{
    string tmp;
    Opra_record rec;// = new Opra_record;
    while(!in.eof()) {
        in >> rec;                 ///***************here 
    }
}
 
int main(int argc, char** argv){
    if (argc < 2)
        return(EXIT_FAILURE);
    ifstream in(argv[1]);
    if(!in)
        return(EXIT_FAILURE);
    parseFile(in);
	return 0;
}

Dragon-

I will include my full code below, I had edited out a few things for brevity.

Why do you not construct the Opra_record here:

Opra_record* rec; // = new Opra_record;

Is there an implicit construction somewhere?

Here is my compile line:

g++ parse_opra.cpp -o parse

I changed the line that you had changed. Same error.

Here is my full code, its just a few more lines.

Thanks again for the quick reply. I appreciate it.

Steve

#include<vector>
#include<string>
#include<iostream>
class Opra_record {
    friend std::ifstream& operator>>(std::ifstream&, Opra_record&);
private:
    std::vector<std::string> stringData;
    std::vector<long> numericData;
    std::string temp;
 
public:
    typedef std::vector<std::string>::size_type size_type;
    Opra_record();
    Opra_record(const Opra_record&);
    ~Opra_record();
    Opra_record(const std::vector<std::string>&);
    size_type size() const;
    std::string& operator[] (size_type i);
    const std::string& operator[] (size_type i) const;
 
};
std::ifstream& operator>>(std::ifstream&, Opra_record&);
 
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "opra_record.h"
using namespace std;
 
void parseFile(ifstream& in)
{
    string tmp;
    Opra_record* rec; // = new Opra_record;
    while(!in.eof()) {
        in >> rec;
    }
}
 
int main(int argc, char** argv){
    if (argc < 2)
        return(EXIT_FAILURE);
    ifstream in(argv[1]);
    if(!in)
        return(EXIT_FAILURE);
    parseFile(in);
}

this compiles without error or warnings using my compiler which is not g++.

#include <fstream>
#include <vector>
using namespace std;
 
class Opra_record {
    friend std::ifstream& operator>>(std::ifstream&, Opra_record&);
private:
    std::vector<std::string> stringData;
    std::vector<long> numericData;
    std::string temp;
 
public:
    typedef std::vector<std::string>::size_type size_type;
    Opra_record() {}
    Opra_record(const Opra_record&);
    ~Opra_record() {}
    Opra_record(const std::vector<std::string>&);
    size_type size() const;
    std::string& operator[] (size_type i);
    const std::string& operator[] (size_type i) const;
 
};
 
std::ifstream& operator>>(std::ifstream& in, Opra_record& r)
{
    return in;
}
 
void parseFile(ifstream& in)
{
    string tmp;
    Opra_record rec;// = new Opra_record;
    while(!in.eof()) {
        in >> rec;                 ///***************here 
    }
}
 
int main(int argc, char** argv){
    if (argc < 2)
        return(EXIT_FAILURE);
    ifstream in(argv[1]);
    if(!in)
        return(EXIT_FAILURE);
    parseFile(in);
    return 0;
}

Dragon-

I will include my full code below, I had edited out a few things for brevity.

Why do you not construct the Opra_record here:

Opra_record* rec; // = new Opra_record;

Is there a implicit construction somewhere?

Is there any reason why 'rec' is a pointer? It seems to me that you simply want to create an instance of Opra_record .. you don't want a pointer to an object, nor do you want to allocate any memory dynamically with new.

simply typing Opra_record rec; will invoke the default constructor for Opra_record

Also - Your overloaded >> operator deals directly with Opra_record objects and not pointers.

Edit - I've just noticed you attempt to read your file while !in.eof() - this is almost always wrong - you should read while the fstream is in a good state, and not until you hit an error.

a better statement would be while ( in >> rec )

>>Opra_record* rec; // = new Opra_record;
you misquoted that. remove the star. Its the difference between static allocation and dynamic allocation. The object is instantiated, and the constructor is called.

Your operator>> function requires a reference to a statically allocated object and you were attempting to pass a pointer. Doesn't work.

>>I changed the line that you had changed. Same error.
you did not change it correctly. it still has the star which is causing the problem.

Dragon-

I will include my full code below, I had edited out a few things for brevity.

Why do you not construct the Opra_record here:

Opra_record* rec; // = new Opra_record;

Your friend function expects a reference to an instance of Opra record, it doesn't matter whether that Opra record has been statically or dynamically created.

Do something like:

Opra_record* rec = new Opra_record( ) ;
// and then use it as
while( in >> *rec )
{
   // your code here
}

OR

Opra_record* rec = new Opra_record( ) ;
Opra_record& ref_rec = *rec ;
while( in >> ref_rec )
{
   // your code here
}

Since I don't have a compiler right now, I havent tested the code, but it should pretty much work out to be well...

Yes. That was simply an error on my part from when I made your modification.

I had tried that earlier as that is how most examples work, but I get this error:

/tmp/cc6rypWo.o(.text+0x12b): In function `parseFile(std::basic_ifstream<char, std::char_traits<char> >&)':
: undefined reference to `Opra_record::Opra_record()'
/tmp/cc6rypWo.o(.text+0x156): In function `parseFile(std::basic_ifstream<char, std::char_traits<char> >&)':
: undefined reference to `operator>>(std::basic_ifstream<char, std::char_traits<char> >&, Opra_record&)'
/tmp/cc6rypWo.o(.text+0x169): In function `parseFile(std::basic_ifstream<char, std::char_traits<char> >&)':
: undefined reference to `Opra_record::~Opra_record()'
/tmp/cc6rypWo.o(.text+0x178): In function `parseFile(std::basic_ifstream<char, std::char_traits<char> >&)':
: undefined reference to `Opra_record::~Opra_record()'
collect2: ld returned 1 exit status

I am using this now:

void parseFile(ifstream& in)
{
    string tmp;
    Opra_record rec; // = new Opra_record;
    while(!in.eof()) {
        in >> rec;
    }
}

Thanks.


p.s. thanks for the other tips and clarifications. *very appreciated*

you did not code the class constructor or destructor.

Opra_record() {}
    Opra_record(const Opra_record&);
    ~Opra_record() {}

you did not code the class constructor or destructor.

Hmm..I don't think that makes a difference in this case since the object will be created irrespective of the initialization of the member variables and desctructors in such small programs are as such better left alone...

I am using this now:

void parseFile(ifstream& in)
{
    string tmp;
    Opra_record rec; // = new Opra_record;
    while(!in.eof()) {
        in >> rec;
    }
}

You forgot to incorporate the tips given to you.
And basically what you are doing is going in the wrong direction. You need not put the while loop in the parseint( ) function but in the overloaded friend function. Something like:

std::ifstream& operator>>(std::ifstream& in, Opra_record& r)
{
    string temp ;
    while( in >> temp )
    {
         // create accessor function for each private variable so that
         // you can retrieve them later from any part of the program
         r.get_string_data().push_back( temp )  ;
     }
}

void parseFile(ifstream& in)
{
    Opra_record rec = new Opra_record( );
    in >> *rec;
}

Thanks for all the replies.

I didn't do the tips because I didn't want to confuse things too much by changing the code outside the problem at hand. They are appreciated though.

The suggestion on how to better write the program doesn't match the algorithm I am trying to implement, I believe.

I have a file of millions of records, I am reading each into the Opra_record object because after each is read I have a bunch of stuff to do with it. After I am done I read the next record. I do that until I have read all the records.

Even after I change the code to this:

void parseFile(ifstream& in)
{
    string tmp;
    Opra_record rec; // = new Opra_record;
    while(in >> rec) {
        in >> rec;
    }
}

I get the undefined error as before:

/tmp/ccpED1KC.o(.text+0x12b): In function `parseFile(std::basic_ifstream<char, std::char_traits<char> >&)':
: undefined reference to `Opra_record::Opra_record()'
....
....

I really think this should just work.

Hmm..I don't think that makes a difference in this case since the object will be created irrespective of the initialization of the member variables and desctructors in such small programs are as such better left alone...


You forgot to incorporate the tips given to you.
And basically what you are doing is going in the wrong direction. You need not put the while loop in the parseint( ) function but in the overloaded friend function. Something like:

std::ifstream& operator>>(std::ifstream& in, Opra_record& r)
{
    string temp ;
    while( in >> temp )
    {
         // create accessor function for each private variable so that
         // you can retrieve them later from any part of the program
         r.get_string_data().push_back( temp )  ;
     }
}
 
void parseFile(ifstream& in)
{
    Opra_record rec = new Opra_record( );
    in >> *rec;
}
Member Avatar for iamthwee

I really think this should just work.

But does it work?

I include the definitions of the constructors as mentioned and moved and consolidated into one source and one header file and it compiled.

Thanks for the help. If I ever run into you in a bar I'll buy you all a beer. :)

>I really think this should just work.
It takes work to get things to work. Your pieces don't fit together because you don't define functions. The default constructor, destructor, and operator>> are never given bodies. That's the core of your problem.

Member Avatar for iamthwee

I include the definitions of the constructors as mentioned and moved and consolidated into one source and one header file and it compiled.

Thanks for the help. If I ever run into you in a bar I'll buy you all a beer. :)

Can you post your full code for the benefit of the community? I like your new avatar! He he :)

Can you post your full code for the benefit of the community? I like your new avatar! He he :)

Sure. Here is my version that compiles.

//parse_opra.h
 
 
#ifndef GUARD_parse_opra_h
#define GUARD_parse_opra_h
 
#include<vector>
#include<string>
#include<iostream>
class Opra_record {
    friend std::ifstream& operator>>(std::ifstream&, Opra_record&);
private:
    std::vector<std::string> stringData;
    std::vector<long> numericData;
    std::string temp;
 
public:
    typedef std::vector<std::string>::size_type size_type;
    Opra_record();
    Opra_record(const Opra_record&);
    ~Opra_record();
};
std::ifstream& operator>>(std::ifstream&, Opra_record&){};
#endif
//parse_opra.cpp
 
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "parse_opra.h"
using namespace std;
Opra_record::Opra_record(){}
Opra_record::Opra_record(const Opra_record&){}
Opra_record::~Opra_record(){}
 
void parseFile(ifstream& in)
{
    string tmp;
    Opra_record rec; // = new Opra_record;
    while(in >> rec) {
        in >> rec;
    }
}
 
int main(int argc, char** argv){
    if (argc < 2)
        return(EXIT_FAILURE);
    ifstream in(argv[1]);
    if(!in)
        return(EXIT_FAILURE);
    parseFile(in);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.