0

I have been trying to find a simple way to return 2 values from a function and found online that creating a structure to store the values was the easiest method of doing so. Now I have written the structure and the function I can not figure out how to actually print the structure. I have seen many other posts about this online, but I don't understand the answers to them. Could anybody please explain to me how I can fix my code without using any technical terms (without explanation). Preferably an addition/modification of my current code with some research material on the subject. I am not experienced in coding at all, nor do I have an education centered around coding. I am just doing this in my spare time for a bit of fun.

#include <iostream>
#include <cmath>

struct values {
    float value1;
    float value2;
};

values quadratic(int a, int b, int c) {
    float d = sqrt(b*b - 4*a*c);
    float x1 = (-b + d)/2*a;
    float x2 = (-b - d)/2*a;
    values result = {x1, x2};
    return result;
};

int main() {
    std::cout << quadratic(1, 2, -1);
};
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • If you want that syntax, then provide the operator the error message you left out of your post is telling you needs to be available to facilitate it. Alternatively, save the result to a local var in `main` and print the members directly or via a helper function. They're public, so that shouldn't be a problem. Regarding "without explanation" ?? That is nearly the entire purpose of this Q&A site. The "why" comes with the "how". – WhozCraig Jan 22 '22 at 11:34
  • 1
    You can define a method to print specific attributes values and call it, or you can redefine the << operator. – Gianluca Bianco Jan 22 '22 at 11:54
  • a tuple is a simpler way to return multiple values if you dont need that struct otherwise – pm100 Jan 22 '22 at 22:06
  • `/2*a` divides by 2 and multiplies by a. You want either `/(2*a)` or `/2/a`. – Nick Matteo Jan 23 '22 at 04:46

2 Answers2

2

There are at least three ways to do this.

Method 1: Get the struct result and print it

This is the simplest solution.

int main() {
    values vs = quadratic(1, 2, -1);
    std::cout << vs.value1 << ", " << vs.value2 << "\n";
}

Method 2: Use automatic structured bindings

This requires C++17 minimum (I think, you shouldn’t be using anything less anyway):

int main() {
    auto [a, b] = quadratic(1, 2, -1);
    std::cout << a << ", " << b << "\n";
}

It’s prettier than Method 1, but basically the same thing.

Method 3: Overload the stream insertion operator

This is where you question was marked as a duplicate and linked to do do exactly this:

std::ostream & operator << (std::ostream & outs, const values & vs) {
    return outs << vs.value1 << ", " << vs.value2;
}

int main() {
  std::cout << quadratic(1, 2, -1) << "\n";
}

This is perhaps the prettiest at the call site, but does require your values struct to be convertible into a string (which is what the overloaded << operator does).

Method 4: Return a tuple instead of a custom struct

This is basically a rehash of 2.

#include <cmath>
#include <iostream>
#include <tuple>

std::tuple <float, float> quadratic(int a, int b, int c) {
    float d = sqrt(b*b - 4*a*c);
    float x1 = (-b + d)/2*a;
    float x2 = (-b - d)/2*a;
    return std::make_tuple(x1, x2);
};

int main() {
    auto [a, b] = quadratic(1, 2, -1);
    std::cout << a << ", " << b << "\n";
};

That’s all I’m gonna bother with off the top of my head, but I think it covers all the bases.

EDIT: fixed dumb thing I wrote

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
0

One common way to do this is to overload operator<<. See this question for further information.

struct values {
    friend std::ostream& operator<<(std::ostream&, const values&);

    float value1;
    float value2;
};

std::ostream& operator<<(std::ostream& os, const values& v) {
  return os << v.value1 << ", " << v.value2;
}
dtell
  • 2,488
  • 1
  • 14
  • 29