4

I would like to be able to have a function that simply gets two input values from the user and returns those values for the main function to work with.

I would like the values a and b to be reside just in the getvals function and be passed into the main function as x and y.

I think I may be going about things the wrong way here as I have searched a lot and can't find any similar ways to do this but any help would be appreciated.

#include <iostream>

using namespace std;


int x = 100;
int y = 42;
int result1;
int result2;
int a;
int b;

int getvals(int,int)
{
    cout << "input value a ";
    cin >> a;
    cout << "input value b ";
    cin >> b;

    return a,b;
}

int main()
{
    getvals(x,y);
    result1 = x + y;


    cout << "\n\n";
    cout << " x + y = " << result1;
    return 0;
}
Prix
  • 19,417
  • 15
  • 73
  • 132
Simon_A
  • 145
  • 2
  • 11

5 Answers5

8

You can only return one value from a function. Fortunately, you can wrap two values in a struct or a class and return that as one object. Which is exactly what std::pair was designed for.

std::pair<int,int> getvals()
{
    std::pair<int,int> p;
    cout << "input value a ";
    cin >> p.first;
    cout << "input value b ";
    cin >> p.second;

    return p;
}

int main()
{
    std::pair<int,int> p = getvals();
    int result1 = p.first + p.second;
    ...
}

C++11 introduces the more general std::tuple, which allows an arbitrary number of elements.

std::tuple<int,int> getvals()
{
    int a,b;
    cout << "input value a ";
    cin >> a;
    cout << "input value b ";
    cin >> b;

    return std::make_tuple(a,b);
}

int main()
{
    int x,y;
    std::tie(x,y) = getvals();
    ...
}
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • I was originally going to answer with `pair` as well, but after re-reading the question, it wasn't what the OP really wanted to do. The question was phrased incorrectly. – jxh Aug 15 '13 at 22:25
  • @jxh: I don't necessarily agree that that is the case. The question may be phrased correctly, and the additional stuff is just his confused attempts at accomplishing that goal. – Benjamin Lindley Aug 15 '13 at 22:38
  • The OP stated: "I would like the values `a` and `b` to be reside just in the `getvals` function and be passed into the main function as `x` and `y`." And, I didn't see how to make that happen with `pair`. You did come up with a nice C++.11 solution with `tuple` and `tie`, though, so +1. – jxh Aug 15 '13 at 22:45
4

Use references for a and b.

void getvals(int &a, int &b)
{
    cout << "input value a ";
    cin >> a;
    cout << "input value b ";
    cin >> b;
}

This declares getvals() to take two reference parameters. Modification to the reference of an object modifies the object that was passed in to the function call.

Without the reference, the parameter is passed by value, which creates a copy of the object passed to the function. Then, modifications made to the parameter in the function only affect the copy.

Alternatively, you can use std::pair<int, int> to return two integer values from your function (it won't need out-parameters then). You can manually unpack the first and second members into your variables x and y, or you can implement a helper class to do that for you. For example:

std::pair<int, int> getvals () {
    std::pair<int, int> p;
    std::cin >> p.first;
    std::cin >> p.second;
    return p;
}

template <typename T, typename U>
struct std_pair_receiver {
    T &first;
    U &second;
    std_pair_receiver (T &a, U &b) : first(a), second(b) {}
    std::pair<T, U> operator = (std::pair<T, U> p) {
        first = p.first;
        second = p.second;
        return p;
    }
};

template <typename T, typename U>
std_pair_receiver<T, U> receive_pair (T &a, U &b) {
    return std_pair_receiver<T, U>(a, b);
}

int main () {
    int x, y;
    receive_pair(x, y) = getvals();
    //...
}

If you have C++11 available to you, you can use the more general tuple and the tie helper to do this similarly in a more clean way. This is illustrated in Benjamin Lindley's answer.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • @Giswin you posted your answer so soon after jxh that I doubt anybody could accuse you of copying. I posted the same too. It happens sometimes, when there's an obvious solution. You don't need to delete your answer. – Dave Aug 15 '13 at 22:21
  • Thank you, I had a feeling that pointers were going to come into it. – Simon_A Aug 15 '13 at 22:48
  • You are very welcome. Please note [there are significant differences between pointers and references](http://stackoverflow.com/a/57492/315052). – jxh Aug 15 '13 at 22:53
  • I assume the down vote is because my answer is technically incorrect in some way. I would appreciate it if someone would enlighten me. Thanks! – jxh Aug 15 '13 at 23:43
2

You seem to be half way to returning through parameters. All you need to change is this:

void getvals( int& a, int& b )
{
    cout << "input value a ";
    cin >> a;
    cout << "input value b ";
    cin >> b;
}

Notice the & before the parameter names, meaning pass by reference. That means when they change in the function, they also change in the caller. No return is needed.

Dave
  • 44,275
  • 12
  • 65
  • 105
  • possibly the name of function would also change from getvals to something like changevals – 4pie0 Aug 15 '13 at 22:25
  • @restart Personally I'd find either name explanatory enough. `fillValues` would also be a possibility. There are many others which would be just as good. – Dave Aug 15 '13 at 22:26
1

Pass the values by reference to your function and change it definitions to return void. Something like this:

void getvals(int &a,int &b)
{
    cout << "input value a ";
    cin >> a;
    cout << "input value b ";
    cin >> b;
    return;
}
Richeek
  • 2,068
  • 2
  • 29
  • 37
0

You can only return one thing from a function. That thing can be an array which can be appropriate in some cases.

More often the Right Thing(TM) will be to declare the variables in your calling function. Pass references to those variables to the function which should set them. Using the references you passed in the function can set the variables in the caller very much like returning them. If you go this route it's probably a good idea to have the function return success/failure and handle all data output through the references.

Good luck. I'm pulling for you. We're all in this together.

Chris Raplee
  • 336
  • 1
  • 5