Calling functions and returning values - c++

I am a beginner in C++.I have a function which returns some parameters that i need ,to use in the rest of my program.I am trying to access that function within another class.I am confused with the way i can do it...Can anyone please help me..?
Following is my code :
void SampleProgram :: myFunction()
{
string sInput;
GetInfo getInfo(sInput); //creating instance of the class containing the function
string sSw="";
string sName="ram";
string sList="list";
getInfo.getRequiredInfo(sSw,sName,sList); //calling the function
}
How can i access the output parameters of getRequiredInfo() ..?and save it if the ouput parameters are as following :string name,int status
Please help me...

You'd have to show us the declaration of getRequiredInfo(), but presumably it's something like
X result = getInfo.getRequiredInfo(sSw,sName,sList);
We don't know what X is without seeing that declaration.

In case getRequiredInfo get the address of the strings, try this:
getInfo.getRequiredInfo(&sSw, &sName, &sList);
Now the function can change the value of the arguments.

You can able to return single value in function.
so You can create struct containing string and int and return that as the result.
struct
{
string name;
int k;
}result;
result r = getInfo.getRequiredInfo(sSw,sName,sList); //calling the function
you can save the output parameters like these:
string _name;
int nk;
_name = r.name;
nk = r.k;

The simplest would be return a pair<string,int> from the function. So your function signarutre would be pair<string,int> getRequiredInfo(const string& s1, const string& s2, constr string& s3);. You can then access the string and int part usinf first and second members of the pair.

It sounds as though getRequiredInfo has the behaviour of both reading from and writing to some of the parameters you've passed in.
In C++, unlike in C#, there's no way to specify that a function should, or must, change the value of a given parameter. Indeed, if you have defined your function like this:
void GetInfo::getRequiredInfo(string a, string b, string c);
then all three parameters will be passed by value meaning any changes made to them inside the function will be changing copies of those objects, rather than the objects themselves.
As other contributors have suggested, if you really want to change the parameters you passed in, you could either do so by passing references:
void GetInfo::getRequiredInfo(string a, string& b, string& c);
or (more typically) by passing pointers:
void GetInfo::getRequiredInfo(string a, string* b, string* c);
However, if you want your function to simply read the parameters and return a value (which is the more accepted term for what you're calling 'output parameters') then you have to express your tuple of "name + status" as a single value.
You could use the built in pair template as someone else just suggested:
pair<string,int> getRequiredInfo(string a, string b, string c);
Or you could define your own struct to do it, like someone else suggested:
struct NameAndStatus
{
string name;
int status;
};
NameAndStatus getRequiredInfo(string a, string b, string c);

Related

Can I call the function like that?

If I have a struct.
struct studentRec
{
string name;
int sid;
string major;
int cohort;
};
Then, I have a function.
int compare_MajorName(const studentRec& s1, const studentRec& s2)
Can I call the function like that?
String major = ECE;
list = new studentRec[n];
compare_MajorName(list[mid], major)
No you can't.
Your function parameters require studentRecs. A String cannot be converted to a studentRec automagically. It wouldn't make sense.
You have two possibilities:
make an overrided function which accepts a String as a second parameter
simply compare the name inside the struct with your String:
list[mid].name == major for exemple

Accessing a variable in a void function to be used in other functions? C++

Is it possible to access the d_nr variable outside of this function without returning it and how would I do that? I want to keep the return value void.
Not sure if this code is any help but this is the function in question. I wan't to access the d_nr variable outside of this function without returning it.
void read(data & P, string file_name)
{
int d_nr = 0, i = 0;
string line;
ifstream D(file_name);
while(getline(D, line))
{
istringstream iss (line);
iss >> P.string[d_nr];
while(iss.good())
{
iss >> P.var_1[i][d_nr] >> P.var_2[i][d_nr];
i++;
}
d_nr++;
i = 0;
}
D.close();
}
You can make it a parameter with reference call.
void read(data & P, string file_name, int &d_nr)
{
d_nr = 0;
...
You can pass a pointer to a extern variable
void read(data & P, string file_name, int *output)
and in the function update the output variable
*output = d_nr;
You can add one more parameter for the function. For example
void read(data & P, string file_name, int &d_nr )
{
d_nr = 0;
//...
Or if data is some class then you can simply add one more data member to this class. For example
void read(data & P, string file_name )
{
P.d_nr = 0;
//...
Is the problem that the function needs a specific signature, but you want additional information?
What, exactly, needs "access"? What kind of threading/process expectations do we have?
A simple global variable could work if there's no multi-threading. You could consider printing the value to stdout (this is probably a bad idea, but I have no idea what the context and requirements are, so it might be what you want.) Or, another related idea that might be terrible but it's hard to say without more detail on what you're doing - you could write it to the file.
Can you be more detailed about what you are trying to do? Probably a static variable would be best, assuming there's no threading issue.
Technically, you can't access a variable declared within the scope of the function if you are not in that scope yourself. Your two options to have access to that value outside of its scope is to either:
Copy its value to some other variable before leaving the scope (before the end of the function in this case). Or...
Declare a variable with a larger scope and use that from within your function.
Ways to do this with the first method include returning the value, or copying the value to a global - like this:
int global_dnr = 0;
void read(data & P, string file_name) {
int d_nr = 0, i = 0;
// The rest of your code as is...
global_dnr = d_nr;
}
Now you can access global_dnr anytime, and it should have the latest d_nr value. If your read function were a class method, you could assign d_nr to a class variable as well.
For approach 2, you don't declare d_nr in your function at all - you can declare a global variable, pass a variable by reference as a parameter (though this is technically equivalent to returning the variable) or access a class member directly. Here is an example using the global variable:
int d_nr = 0; // Here is the global declaration instead.
void read(data & P, string file_name) {
d_nr = 0; // Set variable to 0, but don't declare it here.
// The rest of your code as is...
}
These are your two options. Only the implementation details vary.

C++ same function parameters with different return type

I need to find some way to mock an overload of a function return type in C++.
I know that there isn't a way to do that directly, but I'm hoping there's some out-of-the-box way around it.
We're creating an API for users to work under, and they'll be passing in a data string that retrieves a value based on the string information. Those values are different types. In essence, we would like to let them do:
int = RetrieveValue(dataString1);
double = RetrieveValue(dataString2);
// Obviously, since they don't know the type, they wouldn't use int =.... It would be:
AnotherFunction(RetrieveValue(dataString1)); // param of type int
AnotherFunction(RetrieveValue(dataString2)); // param of type double
But that doesn't work in C++ (obviously).
Right now, we're having it set up so that they call:
int = RetrieveValueInt(dataString1);
double = RetrieveValueDouble(dataString2);
However, we don't want them to need to know what the type of their data string is.
Unfortunately, we're not allowed to use external libraries, so no using Boost.
Are there any ways we can get around this?
Just to clarify, I understand that C++ can't natively do it. But there must be some way to get around it. For example, I thought about doing RetrieveValue(dataString1, GetType(dataString1)). That doesn't really fix anything, because GetType also can only have one return type. But I need something like that.
I understand that this question has been asked before, but in a different sense. I can't use any of the obvious answers. I need something completely out-of-the-box for it to be useful to me, which was not the case with any of the answers in the other question asked.
You've to start with this:
template<typename T>
T RetrieveValue(std::string key)
{
//get value and convert into T and return it
}
To support this function, you've to work a bit more, in order to convert the value into the type T. One easy way to convert value could be this:
template<typename T>
T RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
std::stringstream ss(value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
Note that you still have to call this function as:
int x = RetrieveValue<int>(key);
You could avoid mentioning int twice, if you could do this instead:
Value RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
return { value };
}
where Value is implemented as:
struct Value
{
std::string _value;
template<typename T>
operator T() const //implicitly convert into T
{
std::stringstream ss(_value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
}
Then you could write this:
int x = RetrieveValue(key1);
double y = RetrieveValue(key2);
which is which you want, right?
The only sane way to do this is to move the return value to the parameters.
void retrieve_value(std::string s, double& p);
void retrieve_value(std::string s, int& p);
<...>
double x;
retrieve_value(data_string1, x);
int y;
retrieve_value(data_string2, y);
Whether it is an overload or a specialization, you'll need the information to be in the function signature. You could pass the variable in as an unused 2nd argument:
int RetrieveValue(const std::string& s, const int&) {
return atoi(s.c_str());
}
double RetrieveValue(const std::string& s, const double&) {
return atof(s.c_str());
}
int i = RetrieveValue(dataString1, i);
double d = RetrieveValue(dataString2, d);
If you know your value can never be something like zero or negative, just return a struct holding int and double and zero out the one you don't need...
It's a cheap and dirty, but easy way...
struct MyStruct{
int myInt;
double myDouble;
};
MyStruct MyFunction(){
}
If the datastrings are compile-time constants (as said in answering my comment), you could use some template magic to do the job. An even simpler option is to not use strings at all but some data types which allow you then to overload on argument.
struct retrieve_int {} as_int;
struct retrieve_double {} as_double;
int RetrieveValue(retrieve_int) { return 3; }
double RetrieveValue(retrieve_double) { return 7.0; }
auto x = RetrieveValue(as_int); // x is int
auto y = RetrieveValue(as_double); // y is double
Unfortunately there is no way to overload the function return type see this answer
Overloading by return type
int a=itoa(retrieveValue(dataString));
double a=ftoa(retrieveValue(dataString));
both return a string.
As an alternative to the template solution, you can have the function return a reference or a pointer to a class, then create subclasses of that class to contain the different data types that you'd like to return. RetrieveValue would then return a reference to the appropriate subclass.
That would then let the user pass the returned object to other functions without knowing which subclass it belonged to.
The problem in this case would then become one of memory management -- choosing which function allocates the returned object and which function deletes it, and when, in such a way that we avoid memory leaks.
The answer is simple just declare the function returning void* type and in the definition return a reference to the variable of different types. For instance in the header (.h) declare
void* RetrieveValue(string dataString1);
And in the definition (.cpp) just write
void* RetrieveValue(string dataString1)
{
if(dataString1.size()<9)
{
static double value1=(double)dataString1.size();
return &value1;
}
else
{
static string value2=dataString1+"some string";
return &value2;
}
}
Then in the code calling RetrieveValue just cast to the right value
string str;
string str_value;
double dbl_value;
if(is_string)
{
str_value=*static_cast<*string>(RetrieveValue(str));
}
else
{
dbl_value=*static_cast<*double>(RetrieveValue(str));
}
Since you used an example that wasn't really what you wanted, you threw everyone off a bit.
The setup you really have (calling a function with the return value of this function whose return type is unknowable) will not work because function calls are resolved at compile time.
You are then restricted to a runtime solution. I recommend the visitor pattern, and you'll have to change your design substantially to allow for this change. There isn't really another way to do it that I can see.

Can I use std::set<std::string> as a default parameter for a function?

I'm new to this and now sure whether this is doable. I want to add a argument of std::set<std::string> to a function, and set its default value to be NULL, to avoid impact on previous uses.
So basically,
func(int a); turns into
func(int a, std::set<std::string> & temp = NULL);
but this will give me an error "error C2440: 'default argument' : cannot convert from 'int' to 'std::set<_Kty> &'"
Can anybody help me on this?
Thanks
In order to set the default to NULL, you'd have to be passing an std::set<std::string>*, not a reference to a value type.
Furthermore, if you are passing a non-pointer type and you want to assign any default value at all, it has to be a const reference, because you can't (advisably!) assign a temporary to it otherwise.
So your choices for "default" values are basically:
std::set<std::string>* = NULL
or:
const std::set<std::string>& = std::set<std::string>()
or option 3, using function overloading more directly:
void myfunction() {dothing(0);}
void myfunction(std::set<std::string>& optional_param)
{ dothing(optional_param.size()); }
or option 4, having a corresponding bool indicating whether parameter is "set":
void myfunction(std::set<std::string>& param, bool param_has_meaning=true) {}
It looks like you're already on the track to the third option. You just need to write two definitions, one with and one without the parameter.
You have the right idea - using a reference. However, a reference cannot be NULL by default, like a pointer can. Therefore, what you probably want to do is overload the function so that you use void func(int a) when you don't want to pass a set as a parameter and use void func( int a, std::set<std::string>& temp)
This way, you can actually provide two separate implementations - one that works on a set and one that doesn't. From a usage point of view, it would have the same effect as a default parameter. From a coding point of view, each implementation would have a clearer purpose.
If you're not going to be modifying the set, might I suggest using a const reference instead:
void func( int a, const std::set<std::string>& temp )
You can't have a NULL reference in C++.
The simplest way would be to have a dummy empty set:
std::set<std::string> empty;
void func(int a, std::set<std::string>& temp = empty)
{
// ...
}
You can then call:
func(1);
Neater, still, would be to use function overloading to create a wrapper so that you have no need to default:
void func(int a, std::set<std::string>& temp)
{
}
void func(int a)
{
std::set<std::string> empty;
func(a, empty);
}
// And then...
func(1);
All this assumes that if you pass in a set you're going to modify it somehow. It's not clear from your question what your intention is but I've made the assumption on the basis that your reference is non-const. If I've miscalculated, then the answer is even simpler:
void func(int a, const std::set<std::string>& temp = std::set<std::string>())
{
}
The following will give you an empty set object:
std::set<std::string>()

Passing user input to function with char* parameters

I'm new to this so I know this is probably something simple.
I have a function like this
void GroceryList::addRecord(char* itemName, char* itemType, char rating){
//do some code;
}
My problem is I am having trouble creating proper arguments to pass to the function.
I've tried something like
void main() {
string itemName;
cin >> itemName;
string itemType;
cin >> itemType;
string rating;
cin >> rating;
gradeBook.addRecord(itemName, itemType, rating);
}
I didn't expect it to work as the function is expecting char* but I can't for the life of me figure out how to get the user input into a variable that I can pass to the function. I've been search for literally 13 hours trying what I can find but no luck so far.
Well, don't use char*.
void GroceryList::addRecord(const std::string& itemName, const std::string& itemType, const std::string& rating) { /* ... */ }
You can get const char* (not char*) from string with c_str() member function, e.g. itemName.c_str(), but unless you're doing interop with C libraries, you don't need that.
Change the function prototype to
void GroceryList::addRecord(string itemName, string itemType, string rating){
//do some code;
}
I also recommend const correctness in your code, if you are not going to change the arguments, pass them by ref with const (for performance)
void GroceryList::addRecord(const string& itemName, const string& itemType, const string& rating){
//do some code;
}
All depends on the actual method body which you didn't describe.
Use std::string::c_str(); that's what it's for:
gradeBook.addRecord(itemName.c_str(), itemType.c_str(), rating.c_str());
This function returns a const char *. However, the addRecord function doesn't seem to be const-correct, so you need to fix that.
You can use string and then when passing just call c_str() on the string. For the rating you can just use a char.
Then calling the function looks like:
gl.addRecord(itemName.c_str(), itemType.c_str(), rating);
For this to work you'll need to change the function signature to const char* instead of char*.
The simple answer is that you can't. If you can modify
GroceryList::addRecord, change it to use std::string const&. If you
can't modify it, then you have to ask the question: why does it use
char*? There are two possible answers: the author didn't understand
const, or was too lazy to use it, and in fact doesn't modify the
pointed to strings. In this case, something like
const_cast<char*>( itemName.c_str() ) can be used; it's wordy, but
that's the price you pay when the code's author doesn't do his job
correctly. The other possible answer is that the code does modify
something through the pointer. In this case, the only solution involves
making a copy of the string into a char[], and passing it.