Handling functions with more than one output parameters - c++

How do we handle more than one output parameters in C++.I am beginner in C++ and currently i am trying to write a function A which calls another function B of some other class,Function B consists of 6 parameters in total ,of which three are input parameters and the rest three are output parameters.How can i access all the three output parameters within my function A?I tried to do it in the following way...Can anyone help me to correct my code if i have gone wrong..?Please do help me friends..
class A ::functionA()
{
int in_a=1;
string in_b= "name";
int in_c=3;
int ot_a=0;
int ot_b=0;
string ot_s1=""
ClassB *classB();
classB = classB.functionB(in_a,in_b,in_c,ot_a,ot_b,ot_s1); //is this way correct?
ot_a= ? ;
ot_b=? ;
ot_s1=?
}
can i use something like ot_a=classB.ot_a ?Please help me...

You have got the basic syntax of C++ wrong. ClassB *classB(); does not create any object, it declares a function prototype of function classB which returns ClassB*. To create a object you should do ClassB b; and then use b as you have done. The output variables will be correctly filled up by the function if it is taking its parameter by reference.

For multiple return values, you got generally two choices:
return a struct containing your return values
pass the return values in per reference.
Both examples demonstrated:
// first approach, struct return
struct myReturns{
int int_return;
float float_return;
};
myReturns MyFunc(int param1, char* param2, ...){
// do some stuff with the parameters
myReturns ret;
ret.int_return = 42;
ret.float_return = 13.37f;
return ret;
}
// calling it:
myReturns ret = MyFunc(/*pass your parameters here*/);
int i = ret.int_return;
float f = ret.float_return;
// second approach, out parameters
void MyFunc(int inParam1, char* inParam2, int& outInt, float& outFloat){
// do some stuff with the parameters
outInt = 42;
outFloat = 13.37f;
}
// calling it:
int i;
float f;
MyFunc(/*your parameters here*/,i,f);
// i and f are now changed with the return values

As mentionned in Xeo's answer, you can use return structures or references.
There is another possibility, to use pointers.
Pointers allows you to do one thing : if the function you call can be used to compute multiple informations, but you don't want all of them, you can pass NULL as the value of the pointer so that the function knows it doesn't need to fill these informations.
Of course, the function you call needs to be designed that way, it's not automatic.
void f()
{
type1* p1 = new type1();
type2* p2 = NULL
g(p1, p2);
}
void g(type1* param1, type2* param2)
{
//Do some computation here
if (param1 != NULL)
{
//Do something here to fill param1
}
if (param2 != NULL)
{
//Do something here to fill param2
}
}
But as a general rule, it's better to use references when you can, and pointers when tou have to. If the function doesn't handle the case when a pointer passed to it is NULL, you will end with a crash. References can't be NULL, so they avoid this problem.

Answer is: references.

ClassB *classB();
classB = classB.functionB(in_a,in_b,in_c,ot_a,ot_b,ot_s1);
By looking . operator after classB, I assume that you are thinking classB is an object. No, it is not.
ClassB *classB();
The above statement says - classB() is a function that takes no parameters and return type is a reference to ClassB.

If you can change functionB() then use pointers as parameters. This way you can change the value inside functionB() and they will be changed directly in functionA().

Related

C++ Programming ( advantages of by ref & by val) query? / methods of editing struct other than byRef

I am going over a mock exam in revision for my test, and one question on the paper confuses me.
Q.)An application is required to pass a structure to a function, which will modify the contents of the structure such that on return from the function call the caller can use the new structure values. Would you pass the structure to the function by value, address or reference?
State clearly why you chose a particular method. Justify your choice by comparing the three methods.
Now I have difficulty understanding this, because I assume the best answer to the question would always be by Ref as that takes the reference pointer of the value and edits its contents rather than just getting a copy. This would be different if using a class based program.
The only other method I would understand would be having a separate value and getting and setting the values, but this would mean extra lines of code, I am a little unsure on what this means, can anyone help enlighten me ? I do not know any other methods to achieve this.
This is not "advanced programming"; it is the absolute basics of C++.
Whether return-by-value or "out" parameters (implementing using references or pointers) are "best" for any given use case depends on a number of factors, style and opinion being but two of them.
// Return by value
// T a; a = foo(a);
T foo(const T& in) // or: T foo(T in)
{ // {
T out = in; //
out.x = y; // in.x = y;
return out; // return in;
} // }
// Out parameter (reference)
// T a; foo(a);
void bar(T& in)
{
in.x = y;
}
// Out parameter (pointer)
// T a; foo(&a);
void baz(T* in)
{
in->x = y;
}
The question is asking you what the pros and cons are of these three approaches.

C++ Returning a Reference of an Object

I'm currently in a C++ Course and im struggling with References. I know there are some similar topics, but i couldnt find an answer for this.
The thing is my Prof wants us to use References when returning objects, so return by value or using a pointer as return is no option.
So i guess i have to use a dynamic allocated object (returning a reference to a local object ends in a mess...right?)
1. Complex& method() {
2. Complex *object = new Complex();
3. return *object; }
Here is where im struggling, how do i catch the return right?
1. Complex one = object.method();
As far as i understand, with this i will get only a Copy and a Memory Leak
So how do i catch it with a pointer?
1. Complex *two = new Complex();
2. delete two;
3. *two = object.method();
this seems to work, but is there a way of it in just one line? Or should it be done different?
One idea is to store the returned object inside your object:
class Obj {
public:
Complex &method() { c.data = 10; return c; }
private:
Complex c;
};
This way there isn't any returning of local variable, or heap allocation.
returning a reference is efficient when you returning class member,
like:
class A{
Complex member;
public:
Complex& method(){
return member;
}
};
You also can return reference in manner to return some static or global object that can't be NULL, like:
Complex& method() {
static Complex c; // c cant be null
return c;
}
the advantage of using reference is that you can use the function call as an object, like: cin>>method().real>>method().img; and use the same object even if you call the method several times.
But your code doesn't feet to use reference, because each call creates a new instance.
if you are using dynamic allocation you should return a pointer:
Complex* method() {
return new Complex();
}
and you should remember to delete it.
my Prof wants us to use References when returning objects
When I read this, my first thought was that your professor meant:
void method(Complex& nonConstPassByReference)
{
nonConstPassByReference.data = 10;
}
or
int method(Complex& nonConstPassByReference)
{
nonConstPassByReference.data = 10;
return (0); // no error occurred
}
And when I use this technique, I now use
std::string method(Complex& nonConstPassByReference)
{
std::stringstream ss;
nonConstPassByReference.data = 10;
// more stuff
if (anErrorOccurred)
ss << errorDescriptionInfo << std::endl;
return (ss.str()); // no error occurred when return size is 0
}
This comes from the idea that, in general, all methods or functions can have two kinds of formal parameters. We call them pass-by-value, and pass-by-reference.
In general, all functions / methods can have both input and output formal parameters. And usually, input parameters are pass-by-value. Output parameters are non-const-pass-by-reference, inviting the method body to send its results back to the prebuilt instance of the calling code.
Occasionally, pass-by-reference variables are used for 'input-to-method' parameters (perhaps for performance - to avoid an expensive copy). In this case, the input-to-method-pass-by-reference parameters should be marked with 'const', to ask the compiler to generate an error if the code tries to modify that input.
Note that many C functions do NOT return a value which is part of the action ... return is instead an 'error occurred' indication, with the error description stashed in errno.

Callback functions with different arguments

I have two functions with a little different functionality, so I can't make them as template functions.
int func64(__int64 a) {
return (int) a/2;
}
int func32(int a) {
return a--;
}
Depending on variable b64, I would like to call func64 or func32. I don't want check if b64 is true many times in my code, so I use pointers to functions.
void do_func(bool b64) {
typedef int (*pfunc32)(int);
typedef int (*pfunc64)(__int64);
pfunc32 call_func;
if (b64)
call_func = func64; //error C2440: '=' : cannot convert from 'int (__cdecl *)(__int64)' to 'pfunc32'
else
call_func = func32;
//...
call_func(6);
}
How can I avoid this error and cast call_func to pfunc32 or pfunc64?
The language requires all functions called through the same function pointer to have the same prototype.
Depending on what you want to achieve, you could use the pointer/cast aproach already mentioned (which satisfies this requirement at the loss of type safety) or pass a union instead:
union u32_64
{
__int64 i64;
int i32;
};
int func64(union u32_64 a) {
return (int) a.i64/2;
}
int func32(union u32_64 a) {
return --a.i32;
}
void do_func(bool b64) {
typedef int (*pfunc)(union u32_64);
pfunc call_func;
if (b64)
call_func = func64;
else
call_func = func32;
//...
union u32_64 u = { .i64 = 6 };
call_func(u);
}
Pass a void pointer and cast it in the function body.
Of course this means less compiler control if you use the wrong type; if you call func64 and pass an int to it the program will compile and produce wrong results without giving you any tip of what is going wrong.
int func64(void *a) {
__int64 b = *((__int64*) a);
return (int) b/2;
}
int func32(void *a) {
int b = *((int *) a)
return b-1;
}
I need to call func32() or func64() depending on flag b64
So do that:
void do_func(bool b64) {
if (b64)
func64(6);
else
func32(6);
}
Well, first of all, please note that function func32 is returning the input argument as is.
This is because with return a--, you are returning the value of a before decrementing it.
Perhaps you meant to return a-1 instead?
In any case, you can simply declare this function as int func32(__int64 a).
This way, it will have the same prototype as function func64, but will work exactly as before.
BTW, calling a function through a pointer might be more "expensive" than a simple branch operation, so depending on your application, you might be better off with a simple if/else conditional statement...
Make a wrapper for func64:
int func64_as_32(int a) {
return func64(a);
}
Now you can assign either func32 or func64_as_32 to call_func since they have the same signature. The value you pass in, 6, has type int so passing it to func64_as_32 has the same effect as passing it directly to func64.
If you have call sites where you pass in a value of type __int64 then you'd do it the other way around, wrap func32.
As bool in C++ converts to int ( true => 1, false => 0 ) you can use b64 as array index. So take SJuan76's advice, convert your functions prototype to int f(void*) and put them into array int (*array_fun[2])(void* x); . You can call these functions then like that :
int p = 6;
array_fun[b64](&p);

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>()