Ryan
Ryan

Reputation: 169

A function with variable return type

I want to be able to make a function GetInput() which takes a class as a parameter, and returns whatever is input. The function definition would look like this:

GetInput(class type) {
    if (type == string) {
        string stringInput;
        cin >> stringInput;
        return stringInput;
    }
    else if (type == int) {
        int intInput;
        cin >> intInput;
        return intInput;
    }
    else {
        return NULL;
    }
}

I don't know what to write for the return type of the function because it can be either string or int. How can I make this function work?

Upvotes: 1

Views: 1278

Answers (2)

Peter
Peter

Reputation: 36627

As you've described it, you can't get it to work.

However, since the caller needs to know what type is being read, the simple solution is to use a templated function.

#include <iostream>

//   it is inadvisable to employ "using namespace std" here 

template<class T> T GetInput()
{
    T Input;
    std::cin >> Input;
    return Input;
}

And to use

//   preceding code that defines GetInput() visible to compiler here

int main()
{
     int xin = GetInput<int>();
     std::string sin = GetInput<std::string>();
}

The templated function will work for any type T for which input streams (like std::cin) support streaming and that can be returned by value. You can use various techniques (traits, partial specialisation) to enforce constraints (e.g. produce a meaningful compilation error if the function is used for a type for which the function logic does not work) or to provide different functionality for different types.

Of course, since all you're doing is reading from std::cin, you could actually read directly

#include <iostream>

int main()
{
    int xin;
    std::string sin;

    std::cin >> xin;
    std::cin >> sin;
}

Upvotes: 0

You can't make it an actual argument, but you can do something similar by creating a function template (also called a template function):

template<class T>
T GetInput() {
    T input;
    cin >> input;
    return input;
}

You can use it like this:

string stringInput = getInput<string>();
int intInput = getInput<int>();

getInput<string> and getInput<int> are considered different functions, generated by the compiler - hence why this is called a template.

Note - if you're using multiple files, the whole template definition must go in a header file and not the source file, because the compiler needs to see the whole template in order to generate functions from it.

Upvotes: 7

Related Questions