Passing a 2d vector into a function c++ - c++

I have a function (assign) in a class (graph) in a header file. The objective of this function is to print a 2d vector:
class Graph
{
public:
void printvec(vector< vector<double> >&PRRMap);
};
I call this function from a cpp file such as:
Graph G;
G.printvec(vector< vector<double> > &PRRmap);
I get the following error:
error: expected primary-expression before ‘&’ token
How can I fix this?

void printvec(vector< vector<double> >&PRRMap);
This is a declaration. It includes formal parameters, each of which specifies a type and an optional name.
G.printvec(a_map);
This is a function call. It includes actual parameters, each of which is an expression, aka value. The type is not named during a function call. But you do need to specify the name of the vector you want printed.
The type of the actual parameter expression is checked against the formal parameter type specified in the function declaration. If they don't match, the compiler will look for a suitable conversion, and if it can't find one, you will get a compile error.
Since your function requires a non-const reference, most conversions will not be allowed here. You should specify the name of a suitable vector-of-vectors object that you have prepared with the data to be printed.

when you call the function you don't need the & operator
only the variable (a valid reference)

Related

Can variables be used in function call in ellipsis functions in C++

For this function that takes variable number of arguments,
void func(int count, ...) // ellipsis function
{
// function definition
}
Can a function call be made like follows :
int a{};
double b{};
string c{};
func(3,a,b,c); // using actual variables instead of fixed values in function call
My question is when an ellipsis function is called does it always has to be just fixed values like func(3,5,2.7,"Hi") or can variables be supplied in the function call like so func(3,a,b,c)?
Note that passing classes like std::string, with non-trivial copy constructor or nontrivial move constructor or non-trivial destructor, may not be supported and has "implementation-defined" semantics. You have to check your compiler documentation on how such classes are passed or check if they are supported at all.
Can variables be used in function call in ellipsis functions in C++
Yes.
Can a function call be made like follows
Yes.
when an ellipsis function is called does it always has to be just fixed values like func(3,5,2.7,"Hi")
No.
can variables be supplied in the function call like so func(3,a,b,c)?
Yes.
Can you suggest any reference so I can do some research on it?
https://en.cppreference.com/w/cpp/language/variadic_arguments https://en.cppreference.com/w/cpp/utility/variadic https://eel.is/c++draft/expr#call-12
And in C++ you should strongly prefer: https://en.cppreference.com/w/cpp/language/parameter_pack , because of type safety.
Though ellipsis gives us some useful functionality, it is quite dangerous to use them. When using ellipsis, the compiler does not check the type of arguments passed to the function. So the compiler does not throw any error if arguments are of different types. Even if pass string, double, or bool type values are passed to the average() function it returns return an unexpected value, the compiler does not throw any error.
Source : https://www.geeksforgeeks.org/ellipsis-in-c-with-examples/

I do not understand why this compiles

I'm certainly missing something, but I do not understand why this compiles (with both g++ & clang++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
First of all, B is a type... not a value. How should I interpret this code?
It's interpreted as the declaration of a function named a, which takes one argument of type B and returns A.
It's simply a function declaration declaring a to be a function returning A and taking one unnamed parameter of type B.
It is valid because function declarations as opposed to function definitions are allowed within function definitions.
This issue is known as the most vexing parse. The line A a(B); can be interpreted as the declaration of a function named a returning an object of type A and taking an unnamed parameter of type B.
One way to avoid this issue is to use the uniform initialization syntax which was introduced in C++11, which consists in using braces instead of parenthesis: A a{B}; returns an error. The line is now interpreted as a variable declaration initialized with B, which is a type instead of a value.
Here's more information:
The Most Vexing Parse: How to Spot It and Fix It Quickly

error assigning a function pointer passed as an argument in the constructor to a private instance variable

I'm trying to assign a function pointer that is an argument in the constructor of a class to a private instance variable. (The purpose of this is to be able to pass a callback function to the constructor and use said callback function in member functions of the class.)
I thought I declared the instance variable correctly as a function pointer. The way I read the code snippet, the left operand "cmp" is a pointer, not a function, just like the right operand. (Both are pointers to functions of the same type, or so I thought.) However, the error message says "function as left operand." What am I doing wrong or misinterpreting? Is there a "most vexing parse" issue somewhere?
How can I fix this error and assign the function pointer?
I'm getting the following error message:
"error C2659: '=' : function as left operand"
The error is occurring in the following snippet of code:
template <typename Type>
PQueue<Type>::PQueue(int (cmpFn)(Type,Type))
{
cmp = cmpFn;
}
The compiler is complaining about
cmp = cmpFn;
The constructor prototype is
PQueue(int (cmpFn)(Type, Type) = OperatorCmp);
(OperatorCmp is just another function pointer.)
I declared the instance variable in the private section as
int (cmp)(Type, Type);
The IDE I'm using is Visual C++ 2008 Express, if that matters. (using old version to be compatible with old course materials).
The declaration
int (cmp)(Type, Type);
indeed declares a function, not a function pointer. However, the same syntax used in the parameter list for a function declaration denotes a function pointer, so cmpFn is in fact of type int (*)(Type, Type). Just change the declaration for cmp to
int (*cmp)(Type, Type);
and you'll be good.

The meaning of & as function parameter in a compile error

I'm new to C++ and am trying to interpret what the compiler is telling me. I'm calling the function this way:
Object *clientConnection = new Object();
function(clientConnection);
and getting the following error:
error: no matching function for call to 'function(Object*&)'
I'm trying to give a meaning to the following part Object*&. If I passed a pointer of the Object to the function what's with catch with the &?
It means you passed an lvalue of type Object*. If you passed an rvalue of type Object*, you would see a different error:
function(&*clientConnection);
should give
error: no matching function for call to 'function(Object*)'
This information is part of the error message, because some functions can only be called with lvalues, and if you pass an rvalue, this lack of & points you towards the problem.
You could implement function(clientConnection) in two ways
Call by value where the content of variable clientConnection will
be copied in 'p'
void function(Object* p)
Call by reference where 'p' is an alias of clientConnection in
function body.
void function(Object* &p)
When both of above definitions are missing, the compiler prints one of them mostly
function(Object*&)

int transforms into int&?

code snippet:
// some code
SDL_Surface* t = Display->render_text(text);
int z=100;
Display->blit_image(t,z,100);
// some more code
does not compile because z magically changes to an int&,
file.cpp:48: error: no matching function for call to ‘display::blit_image(SDL_Surface*&, int&, int)
how can this happen?
post scriptum:
the following works if i put them in place of Display->blit_image(t,z,100)
Display->blit_image(t,z,100,0);
but i am sure that th 4th param is optional because the exact same function works elsewhere without it
pps: i created a minimal-case of my code that behaves as describd above
it's 3 files:
monkeycard.cpp: http://pastebin.com/pqVg2yDi
display.hpp: http://pastebin.com/xPKgWWbW
display.cpp: http://pastebin.com/nEfFX1wj
g++ -c display.cpp monkeycard.cpp fails with:
monkeycard.cpp: In member function ‘void monkeycard::messagebox(std::string)’:
monkeycard.cpp:28: error: no matching function for call to ‘display::blit_image(SDL_Surface*&, int&, int)’
display.hpp:26: note: candidates are: void display::blit_image(SDL_Surface*, int, int, SDL_Rect*)
The error message tells you what you're trying to pass. With automatic conversions and whatnot, that doesn't mean the function must have exactly that signature.
int& here just means that the parameter you've provided is an lvalue, and so it could be passed as a non-const reference. A function can match with that parameter as an int&, const int&, int, long, const float&, etc.
the point is that if instead of z i
write 100 it works.
That's interesting. I can't immediately think of a way to write a function that accepts an integer literal, but not an integer variable. The following code compiles, of course:
struct SDL_Surface;
struct SDL_Rect;
struct display {
void foo(SDL_Surface* img, int x=0, int y=0, SDL_Rect* clip=0) {}
};
int main() {
display d;
int z = 0;
SDL_Surface *p = 0;
d.foo(p,z,100);
}
So there must be something else you haven't mentioned yet, which causes the issue.
Edit: visitor and Charles Bailey (in a comment) have the answer. The defaults are missing from your declaration of the function, so as far as the compiler is concerned you are trying to call a 4-parameter function with 3 arguments. The & is not the problem.
For future reference: when James McNellis asked you for "the" declaration of your function, he meant the declaration which is visible in the translation unit making the call. In your pastebin code, the definition is not visible in that translation unit, and the compiler cannot reach in to a completely different .cpp file and realise that the function is supposed to have parameter defaults. In C++, default values are set up in the calling code, for reasons to do with how calling conventions work.
Having seen the code, the defaults should be given in the header and not in the implementation file.
When you are compiling "monkeycard.cpp", the compiler has only the information in the headers to work with. The compiler has no idea that blit_image has default arguments, and therefore cannot match the function to call.
I suspect that the function isn't declared properly.
There needs to be a prototype inside the class display scope such as:
void blit_image(SDL_Surface* img, int x=0, int y=0, SDL_Rect* clip=NULL);
When you pass an int & parameter (such as any named variable of type int) to an int argument, the value of the int & is copied into the new object of type int. The difference in types implies a conversion which entails a copy which implements pass-by-value. That is just how the C++ formalism works.
The error message you see is nothing else than a specific convention, which that particular compiler uses to generate error messages in cases like that. Apparently, when the compiler is unable to resolve a function call, it generates an error message where every Lvalue argument is reported as having reference type and every Rvalue argument is reported as having non-reference type. This makes some sense, since references in C++ exist specifically for implementing the concept of run-time-bound Lvalue. In fact, it might even turn out that this is exactly how the overload resolution is implemented internally in that compiler.
As for the reason for the error: the function you are trying to call does not exist (or exists, but has a non-matching set of parameters).
P.S. You said in the comments that the matching function actually does exist. That would mean that there's either a problem with the visibility of the function declaration, or a problem with the code you posted being "fake" (i.e. it is not the code you were actually compiling).
Primitives are not reference types in C++.
How do you know that it's the int& that's the cause for the error? The error simply says that the signature is in error. I'd recommend going back and checking the method signature to see what the root cause is.