Using enum within struct

What is wrong with the code below? When I'm trying to compile it with gcc, it gives an error. What if I do want to define enum within the struct?

input:

#include <iostream>
#include <string>
using namespace std;

struct person_t
{
string name;
enum Gender_T {MALE, FEMALE};
Gender_T gender;
};

person_t person1;

int main()
{
cout << "Enter name and gender:\n";
cin >> person1.name >> person1.gender;
}

output:

g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:17: error: no match for ‘operator>>’ in ‘std::operator>> [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](((std::basic_istream<char, std::char_traits<char> >&)(& std::cin)), ((std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)(& person1.person_t::name))) >> person1.person_t::gender’
/usr/include/c++/4.4/istream:119: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, .....some text...............
...................

_Traits>::operator>>(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]
make: *** [test] Error 1
Apparently operator>> doesn't convert person_t to int.
You could tryint g; cin>>g; person1.gender = person_t::Gender_T(g); though I'm not sure this will work.
If you want the app to make sense and ask for a word "male" or "female" you'll have to put a little more work into it.
Last edited on
An enum is a distinct type. There are no predefined overloads for I/O of enumerations. Write your own.

You should be aware that writing extraction operators is tricky, and is not typically a brand-new beginner topic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <cctype>
#include <iomanip>
#include <iostream>
using namespace std;

...

istream& operator >> ( istream& ins, person_t::Gender_T& gender )
  {
  static const char* valid = "female";
  unsigned index;

  ins >> skipws;

  // Figure out whether the initial input is acceptable
  switch (tolower( ins.peek() ))
    {
    case 'm': gender = person_t::MALE;   index = 2; break;
    case 'f': gender = person_t::FEMALE; index = 0; break;
    }

  // Scan past the word "male" or "female", checking to see that
  // it is correct along the way. Abbreviated forms are OK.
  if (ins)
    {
    while (valid[ index ] && isalpha( ins.peek() ))
      {
      // Is the potential input invalid?
      if (tolower( ins.peek() ) != valid[ index ])
        {
        ins.setstate( ios::badbit );
        break;
        }
      // It is OK. Read it so that we can check the next potential input.
      ins.get();
      index++;
      }
    }

  return ins;
  }

Writing insertion operators is significantly easier:
1
2
3
4
5
6
ostream& operator << ( ostream& outs, const person_t::Gender_T& gender )
  {
  if (gender == person_t::MALE) outs << "Male";
  else                          outs << "Female";
  return outs;
  }

Now you can use these easily:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
istream& operator >> ( istream& ins, person_t& person )
  {
  ins >> person.name;
  ins >> person.gender;
  return ins;
  }

ostream& operator << ( ostream& outs, const person_t& person )
  {
  return outs << person.name << " " << person.gender << endl;
  }

int main()
  {
  person_t user;
  cout << "Please enter your first name and gender: " << flush;
  cin >> user;
  cout << "Hello, " << user.name << "! What a "
       << ((user.gender == person_t::FEMALE) ? "gorgeous lady" : "handsome fellow")
       << " you are!\n";
  return 0;
  }

Hope this helps.

Warning! I did not test this code!
Wow! Great. Thanks a lot, Duoas. I'll test it now.
Thank you, too, hamsterman. Your method works, though not perfectly.
Last edited on
Topic archived. No new replies allowed.