1

I have a basic Student class (has to be a class)(yes there is no encapsulation and also namespace pollution pls forgive) and I would like to create custom extraction and insertion operators. After countless searches it still would not work. What I have is this

#ifndef student
#define student

#include <iostream>
#include <string>

using namespace std;

class Student
{
    public:
        string name;
        double score;

        Student();
        Student(string name, double score) : name(name), score(score) {}

        friend ostream& operator<<(ostream &out, Student &student);
        friend istream& operator>>(istream &in, Student &student);
};

#endif

#include "student.h"

ostream& operator<<(ostream &out, Student &student)
{
    out << student.name << ", " << student.score;
    return out;
}

istream& operator>>(istream &in, Student &student)
{
    if (!in >> name || !in >> score)
    {
        in.setstate(ios::failbit);
    }
    return in;
}

I have tried many things from this->name to Student::name to name to Student::student.name to changing the function signature that actually did end up working except it did not actually overload the operator. pls halp :D

Edit: As for the specific problem, it is acessing the member of the Student class within the method. student.name and student.score are throwing an

expected primary-expression before '.' token

and the bottom one is simply a relic of throwing different solution at it but it's scope error.

Edit2: The problem turn out to be a conflict with the guard in the header being called student thus the pre-processor would nuke the word student everywhere -_- Thanks for the help

Boris N
  • 33
  • 5
  • 1
    Welcome to StackOverflow! What is the actual error message you're getting? – mindriot Feb 08 '16 at 20:38
  • 1
    in `operator>>`, you can't just have `name` and `score`. Besides that: you don't actually tell us what the problem is (compiler error? specify the exact text. runtime error? tell us what line the error occurs on). – crashmstr Feb 08 '16 at 20:39
  • 2
    Two quick notes: (1) in your `operator<<()`, you should use `const Student&` (the object does not get changed). (2) In your `operator>>()` implementation, you can just write `return (in >> name >> score);`, no need to worry about the state yourself, it's taken care of. – mindriot Feb 08 '16 at 20:40
  • And, yes, to expand on @crashmstr's comment: you need to use `student.name` and `student.score`. – mindriot Feb 08 '16 at 20:41
  • for the top one, student.name expected primary-expression before '.' token, and the bottom is definitely not right but it's a scope issue – Boris N Feb 08 '16 at 20:41
  • 1
    Don't put `using namespace` directives inside of a header file – Joel Cornett Feb 08 '16 at 20:42
  • You have `#ifndef student` then use `student` as a variable name. Include guards should be something more distinct (Since you `#define student`, then your parameter name is problematic). – crashmstr Feb 08 '16 at 20:47
  • @JoelCornett Is this due to namespace pollution or is there another reason. I'm fairly new to c++. Thanks. – Boris N Feb 08 '16 at 20:48
  • @BorisN Yes, it is due to namespace pollution. See for instance here http://stackoverflow.com/questions/14575799/using-namespace-std-in-a-header-file – Captain Giraffe Feb 08 '16 at 20:51
  • Don't insert [Solved] in the title. Check the answer that was most helpful to you. – Captain Giraffe Feb 08 '16 at 20:55
  • @CaptainGiraffe fixed that. Sorry I'm new. :D (pls don't murder me :P) nah Thanks for the information I'll make sure to do that instead next time. – Boris N Feb 08 '16 at 21:04

2 Answers2

4

Various problems have been pointed out in the comments and in Captain Giraffe's answer. Another more critical problem is this:

You declare a variable called student in your functions; but your header actually #defines student in the header guard! So your #defined symbol clashes with your variable name, resulting in the errors you see. A recommended syntax for the header guard is something like

#define STUDENT_H_INCLUDED
mindriot
  • 5,413
  • 1
  • 25
  • 34
  • o now i get the error on studnet.name and student.score ... im dumb :D thanks. I guess eclipse _guard thing is nicer than i originally thought. – Boris N Feb 08 '16 at 20:46
  • 1
    Or, if you can, `#pragma once` and rid yourself of include guards. – DeathTails Feb 08 '16 at 20:47
3

I see a few problems with your >>

if (!in >> name || !in >> score)

! has higher priority than >>, use !(in >> student.name)

use student.name and student.score

Just as you did in the previous operator.

It is useful to use a const reference to the second argument for the << operator. Change the friend declaration accordingly.

Captain Giraffe
  • 14,407
  • 6
  • 39
  • 67