0

Sorry for the awkward question.

I was wondering if it was possible for a struct in C++ to give one of its members when it itself is called:

Something like this:

struct fooStruct
{
   int a;
   int b;
}

//some stuff

fooStruct bar = {1, 2}

cout << bar << endl //prints 1 or a
cout << bar.b << endl //prints 2

I hope that makes it more clear, thank you for answering!

HarpoN
  • 73
  • 1
  • 9
  • 2
    I think if you overload [`operator<<(..)`](https://stackoverflow.com/questions/476272/how-to-properly-overload-the-operator-for-an-ostream) it is possible, but It should be awkward for readers/users – Amadeus Dec 03 '19 at 13:56
  • overloading operator <<() should work but be a little unexpected to someone using your code that it would print only `a`. – drescherjm Dec 03 '19 at 13:57
  • 1
    Does this answer your question? [How to properly overload the << operator for an ostream?](https://stackoverflow.com/questions/476272/how-to-properly-overload-the-operator-for-an-ostream) – eike Dec 03 '19 at 13:58
  • Printing was just an example. Something like 'int c = bar' or using function dee(int i) as dee(bar) – HarpoN Dec 03 '19 at 13:59
  • 1
    You probably should add the additional information to the question. – drescherjm Dec 03 '19 at 14:05
  • `int c = bar` can be done with other `operator` implementations, but be careful about these and doing non-intuitive operations (e.g. implement `operator/` to multiply) – crashmstr Dec 03 '19 at 14:07

1 Answers1

4

I'm going to start by unwrapping some of your terminology to make the question less ambiguous. If any of these points don't match, this part of the answer won't apply.

  • "give one of its members": you wish to be able to name the object bar, but have the result be more about object's member a

  • "when it itself is called": when its name is passed to a stream (it's not a function!)

  • "when it is referred too": as above (referring to it in one particular scenario/context)

For this, you overload operator<<. That is a way to tell the computer what you want to happen when you call << with a stream and an object of type bar. The implementation of that operator can do whatever you like, including streaming a member variable.

It might look like this:

std::ostream& operator<<(std::ostream& os, const fooStruct& bar)
{
    os << bar.a;
    return os;
}

When this operator overload exists and is in scope, std::cout << bar << std::endl; will do what you've asked for.

When it doesn't or isn't, that line will not compile because the computer has no instructions by which it can know what it means to serialise a bar.

Returning the os reference from such an operator is conventional, and permits chaining. You can read more about this in your C++ book.


If instead you want to permit any fooStruct to be treated as an int, and for that int to have the value of its member a, you can create an implicit conversion:

struct fooStruct
{
   int a;
   int b;

   operator int() { return a; }
}

However, there is a limit to the number of implicit conversions that the compiler can make at any one time (which can be a bit of a pain), and implicit conversions can result in behaviour that the user of your class does not expect. In general, you should avoid this, and just write bar.a instead. It's much clearer.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055