Enum reference argument transfer instead of int reference argument - c++

I have the following code :
typedef enum {Z,O,T} num;
bool toInt (str s,int& n);//<-if convert is possible converts s to integer ,puts the result in n and returns true,else returns false
I want to use toInt function and transfer as a second argument ,argument of type num
num n;
toInt("2",n);
This causes compilation error.
cannot convert parameter 2 from 'num' to 'int &'
I tried to use a cast : toInt("2",(num)n); But it is still problematic
How can I solve the issue?

A value of type num isn't an int, so it has to be converted to a temporary int before it is passed to the function. Tempories cannot be bound to a non-const reference.
If you want to convert via an int, you will have to convert in two steps:
int temp;
toInt("2", temp);
num n = static_cast<num>(temp);

I'd suggested, you add a new enum type for signaing invalid enum e.g:
enum num {Z,O,T,Invalid=4711} ;//no need to use typedef in C++
and change the signature to num instead of int:
bool toInt (str s, num& n)
{
if ( s=="Z" ) n=Z;
else if ( s=="O" ) n=O;
else if ( s=="T" ) n=T;
else { n=Invalid; return false; }
return true;
}
regards

Related

C++ Pointers and Functions with no return - need to recall the output as a pointer

Write a C++ code that calls the function add_three() that takes three float numbers and add them together, the function should not return anything, and the output variable should be passed as an input to the function. Note: the number of argument is four.
#include <iostream>
using namespace std;
void add_three(float, float *);
int main()
{
float s,r;
float a[3];
add_three(a[3], &r); //use of undeclared identifier 'a'
cout<< "The sum is " << s; //use of undeclared identifier 's'
return 0;
}
void add_three(float a[3], float *s)
{
float r = 0;
for(int i=0; i<3; i++)
{
cin >> a[i];
r = r + a[i]; //invalid operands to binary expression ('float *' and 'float')
}
*s = &r;
}
Errors:
assigning to 'float' from incompatible type 'float *'; remove &
*s = &r;
I am stuck and can't understand what I am doing wrong (BTW, I am a complete novice).
The first problem is that you attempt to pass a single float value to the function, which is declared to take a single float value.
Then you create an overload of that function, which takes a pointer to a float value. The function declaration
void add_three(float, float*);
is different from
void add_three(float*, float*);
You also make it worse by passing the fourth element from your three-element array.
Then there's the assignment
*s = &r;
It tries to assign the pointer to the variable r (the type of the expression &r is float*) to the floating-point value *s.
You probably want
*s = r;
Or better yet, use proper references to pass s by reference:
// First argument: Pass a pointer to the first element of the array
// Second argument: Pass a reference to the variable
void add_three(float* a, float& s);
Call as:
float a[3];
float s;
add_three(a, s);
As an alternative you could return the sum instead of passing references. This is actually the method I recommend:
// First argument: Pointer to the first element of your array
// Returns: The sum of all three elements
float add_three(float* a);
Call as:
float a[3];
float s = add_three(a);
Or considering that you don't actually use a in the main function, you could skip passing it as an argument. In fact, you don't need an array at all:
float add_three()
{
float input, sum = 0; // Initialize sum to zero
for (unsigned i = 0; i < 3; ++i)
{
// Note: Really need some error checking and validation here
std::cin >> input;
sum += input;
}
return sum;
}
Simply call as:
float s = add_three();
Even if you must use arguments to "return" the value, you can do it without the array.

do variables automatically convert to the type required by the function as the appropriate arguments?

do variables automatically convert to the type required by the function as the appropriate arguments?
#include <stdio.h>
void swap(int &i, int &j) { //the arguments here are int&
int temp = i;
i = j;
j = temp;
}
int main(void) {
int a = 10;
int b = 20;
swap(a, b); // but a and b does not match the exact types of arguments
cout >> "A is %d and B is %d\n" >> a >> b;
return 0;
}
The type conversion rules are rather complex to explain in general.
But for your example, both parameters are int&, which means "reference to int". Since you pass two valid int variables, it's exactly the type expected and the reference of the variables is passed as argument.
Would you have tried with a different type, it would have failed, for example :
long a=10,b=20; would have failed to compile since it is not possible to get an int reference to refer to the non-int original variables.
swap(10,20); would have failed, because the parameters are literal int values and not variables. It is not possible to get a reference to such a value.
const int a=10; would also have failed. This time because the const of the variable is an additional constraint that the parameter passing is not allowed to losen.
Not related: You should include <iostream> and the output should look like:
std::cout << "A is "<< a << " and B is " << b << std::endl;;
The short answer is "sometimes".
The long answer is very long, and you should read this web page: https://en.cppreference.com/w/cpp/language/implicit_conversion
There are a lot of rules for when various types are implicitly converted to other types -- and when they are not.

Passing a pointer to a function while some (not all) arguments are specified

In the following simple code in C++, I introduce a trivial procedure, 'count_out', which takes in a (pointer to a) function f(i), which takes an int argument and returns an int, and evaluates this function at 10 successive points and prints out the results.
Now 'count_out' works fine with a function like 'multiplyby2' which takes an int and returns an int.
However, I want to feed the 'count_out' procedure with a function like 'add', which takes in two int's; but in order for 'add' to look like 'int f (int)' function, I specify the second argument (b) as e.g. 10.
But how can I make C++ understand this: To take 'add' with the second argument specified, as a function which takes in a single int and returns int, so that I can feed it to 'count_out'?
// C++ code snippet:
#include <iostream>
using namespace std ;
int multiplyby2 (int i) {
return 2 * i ;
}
int add (int a, int b) {
return (a + b) ;
}
void count_out( int (*f) (int) ){
for(int i=1; i<=10; i++) cout << f(i) << endl ;
}
void main() {
count_out ( &multiplyby2 ) ; // works fine.
count_out ( &add ( ,10) ) ; // produces compilation errors!
//note that 'add (int a , 10 )' would be a function which returns a + 10 .
}
A lambda should do the trick:
count_out([](int n) { return add(n, 10); });
Non-capturing lambdas are implicitly convertible to the respective function pointer type.

Error: cannot convert from 'long' to 'int &'

my function get_num returns a variable of long int.
I want to write the next operator:
long int& operator [] (long int i) {
long int a = get_num(i);
int& b = a;
return b;
}
but I got the next error:
error C2440: 'initializing' : cannot convert from 'long' to 'int &'
error C2440: 'return' : cannot convert from 'int' to 'long &'
how can I fix it without changing the function of get_num?
any help appreciated!
I have a class:
class B {
B* next;
long int nom;
long int denom;
public:
long int get_nom() {return nom; }
long int get_denom() {return denom; }
};
class List {
B* head;
public:
long int& operator [] (long int desired_denom) {
// here I search the node that containts the denom that is equal to desired_denom
// and insert it to tmp (it's a pointer to B).
long int a1 = tmp->get_nom()
long int& a2 = a1;
return a2;
}
};
now in the main, I want to do:
int main() {
A a; // assume that it creates the list of B and put values in each node (each B)
// here I want to do:
a[2] = 3; // it should search the node that his denom is equal to 2, and puts 3 instead of his nom
return 0;
}
for example:
if my list is:
(nom=5, denom=6)->(nom=1,denom=8)->(nom=4, denom=2)->NULL
the line a[2]=3 searches the node that his denom is 2 (it's the third node) and set his nom to 3.
so after this line, my list will be:
(nom=5, denom=6)->(nom=1,denom=8)->(nom=3, denom=2)->NULL
Currently in your code there isn't a way to modify the nodes the way you want to. get_nom will have to be changed to return a reference before it can behave the way you would like. Right now you can only make copy of the values in each node of the linked list.
Assuming tmp is set correctly you can return the reference returned by get_nom
long int& operator [] (long int i) {
//Get tmp here probably by list traversal
return tmp->get_nom(i);
}
And then the implementation of get_nom. It is important to note that nom must be a value with a lifespan long enough to be of use as explained below. Returning nom which is private to the class and therefor will not fall out of scope when the function returns should work.
long int& get_nom() {return nom; }
get_nom must return long int& for this to work. There is an important difference between returning long int and long int&. When the return type is long int a copy of the value you are returning is made and passed to the caller. When you return long int& or in other words return a long int by reference, the reference points to the location in memory where the value is stored. This reference allows you to change the value of a long int while it is still stored in the middle of an array or whatever data type you are using.
Another important side effect of this is that if you return a reference to a local variable, when the variable falls out of scope, the value will no longer exist in memory. I haven't actually tried compiling and running this so I'm not sure if the compiler will get mad or what exactly the result will be, but I know it won't be good:
long int& operator [] (long int i) {
long int a = i + 5; //arbitrary change
return a;
}
In this case you are returning a reference to the location of a, but because a falls out of scope after the function finishes executing, the reference no longer points to anything at all. The variable you are returning a reference to must still exist after the function exits.
The compile error is for this line
int& b = a;
^^^^
It should be
long int& b = a;
^^^^^^^^
And, as friends have said in the comments, returning a reference to a local variable leads to a undefined-behavior because that referenced variable will be destroyed after exiting the function.
Blindly asnwering, you might need return a reference to the get_num, if get_num is returning a reference correctly.
return get_num(i);

C++, error invalid conversion from `int*' to `int'

I have the following C++ code:
#include <iostream>
using namespace std;
int main(){
}
int findH(int positionH[]){
return positionH; //error happens here.
}
The compiler throws an error:
invalid conversion from `int*' to `int'
What does this error mean?
positionH[] is an array, and its return type is int.
The compiler will not let you do that. Either make the parameter an int:
int findH(int positionH){
return positionH;
}
Or make the return type a pointer to an int:
int* findH(int positionH[]){
return positionH;
}
Or convert the array to an integer before return:
int findH(int positionH[]){
return positionH[0];
}
This line is invalid C++ (and invalid C too, which your code appears to be written in):
int bla[2] = findH(field, positionH);
bla is an array of 2 elements and cannot be initialised that way. findH returns int.
This error is coming while you are trying to do:
int *p =10;
that means you are assigning int value to pointertoint *p .
But pointer is storing address that means *p is taking 10 as address.
So
just do:
int i=10;
int *p=&i;
or
p=&i;
it will not give any error.
The error was caused because you returned a pointer and the compiler is expecting a int.
There is a very BIG difference between int * and int.
Also why are you returning positionH, arrays are passed by reference, there is no need to return it.
Better code would be
void option1(char** field, int[])
{
int findH(char **, int[]);
int positionH[2];
findH(field, positionH);
//positionH passed by reference, no need to return it
}
void findH(char **field, int positionH[])
{
for(int n = 0;n < 14 ; n++)
{
for(int m = 0; m < 14; m++)
{
if(field[m][n] == 'H')
{
positionH[0] = n;
positionH[1] = m;
}
}
}
}