I am reading The C++ Programming Language by Bjarne Stroustrup. It states an example to explain function-pointers:
int cmp1(const void∗ p, const void∗ q) // Compare name strings
{
return strcmp(static_cast<const User∗>(p)−>name,static_cast<const User∗>(q)−>name);
}
Then it uses this cmp1 in ssort, something like this:
int main()
{
cout << "Heads in alphabetical order:\n";
ssort(heads,6,sizeof(User),cmp1);
print_id(heads);
//Rest of function body
}
My question is: is &cmp1 being passed as an argument in ssort() because we can't pass a function as an argument, we can only pass a function-pointer?
My question is: is &cmp1 being passed as an argument in ssort() because we can't pass a function as an argument, we can only pass a function-pointer?
Your code does not use &cmp1. Hence, your question does not match your code.
Still, a function can be passed without using the addressof operator (&).
ssort(heads, 6, sizeof(User), &cmp1);
is the same as
ssort(heads, 6, sizeof(User), cmp1);
Functions decay to function pointers in this context.
A functions name indeed represent the starting address of the executable code for the function. So it's more like the arrays where its name can be used as pointer to the array itself. Also go through
https://www.geeksforgeeks.org/function-pointer-in-c/
Related
I have 10 functions with generic names which return references like:
int& function0();
int& function1();
...int& functionN();
As you can see only one letter changes in the function name. Each function does a different job. My use case is given some length, say L, I have to call functions from 0 to L. So I want to somehow generate these function names and call them instead of hardcoding all the function calls based on L. So if in a loop where index i is from 0 to L, for each i I want to call functioni().
One approach that I tried was to store these functions into an array of function pointers but that does not work as these functions return references and array of references is not possible. I also tried to use macro concatenation to generate function names but that is also not possible because macro cannot substitute the value of some variable at preprocessing (MACRO(function,i) does not substitute value of i, concatenates to functioni).
How can I do such thing in C++?
That's not possible in C++, but in your case an array of function pointers seems like a good solution:
typedef int& (* functionPtr)();
functionPtr functions[N];
// or without typedef: int& (* functions[N])();
functions[0] = foo; // assign a function named foo to index 0
int& i = functions[0](); // call function at index 0
You could store an array of function pointers, as answered by Zenith.
In C++11, you could have an array of function closures, e.g. use std::function and lambda expressions. You could have some std::map<std:string,std::function<int&(void)>> associating names to closures.
You could wrap the calls in some function like
int& dofunction(int n) {
switch 0: return function0();
switch 1: return function1();
/// etc...
};
and you could write some small script (e.g. in awk, python, shell, etc....) to generate the C++ code of the above dofunction.
At last, on some operating systems (e.g. Linux and most POSIX), you could retrieve a function pointer at runtime by its name using dlopen(3) (with a NULL filename) then dlsym. You would then declare extern "C" int& function0(); (to avoid name mangling -otherwise you need to pass the mangled name to dlsym) and you need to link the program with -rdynamic -ldl; see C++ dlopen mini howto.
I am working on a piece of structured programming homework that requires that I make a program that allows the user to enter names blah blah blah and so on. What I want to do after putting names into the string array is to print them to the screen. I had hoped to accomplish this by passing the array and the number of names contained therein to a function that would then print them to the screen. I wanted to pass the array and number of names as constants so that it would safeguard them so they couldn't be modified by the function, just read-only. I don't understand why I can't put const before the string array or the number of names though.
void writeNames (const string namelist[], const int number_of_names)
Is this something I just have to accept or is there a way I can pass both of those as read-only to the function? I can complete the homework without this so this is more a question of curiousity than a "help me with my homework" one.
P.S. Vectors seem to be a way of doing a lot more things with strings and such, but we haven't got to them in class yet and therefore I can't use them yet either.
Thanks
Without seeing what you're doing within the function, it's hard to answer the question, but my crystal ball says that you're probably doing something that could potentially modify one of the parameters within your method, so the compiler is complaining because you declared the parameter const.
As an example, something like this works just fine:
void writeNames(const std::string namelist[], const int number_of_names)
{
for(int i = 0; i < number_of_names; i++) {
std::cout << namelist[i] << std::endl;
}
}
However, something like this would cause a compiler error, since you're changing one of the variables:
void writeNames(const std::string namelist[], const int number_of_names)
{
while(number_of_names--) { // <-- We're modifying a const value here
std::cout << namelist[count] << std::endl;
}
}
Incidentally, putting the const modifier on your "number_of_names" parameter is somewhat redundant since you're passing the parameter by value, so changing the value within the function would have no effect on the value of the input parameter in the calling function. A change in any of the strings in the array, however, would be reflected in the calling function, so the const modifier there makes sense. Generally you would use const only on parameters that are either pointers, or being passed in by reference.
I am learning D and have mostly experience in C#. Specifically I am trying to use the Derelict3 Binding to SDL2. I have been able to get some basic functionality working just fine but I have become stumped on how to create an array argument for a specific call.
The library contains a call
SDL_RenderDrawLines(SDL_Renderer*, const(SDL_Point)*, int) //Derelict3 Binding
And I have been unable to correctly form the argument for
const(SDL_Point)*
The SDL Documentation for this function states that this argument is an array of SDL_Point, but I am unclear how to create an appropriate array to pass to this function.
Here is an example of what I have at the moment:
void DrawShape(SDL_Renderer* renderer)
{
SDL_Point a = { x:10, y:10};
SDL_Point b = { x:500, y:500};
const(SDL_Point[2]) points = [a,b];
Uint8 q = 255;
SDL_SetRenderDrawColor(renderer,q,q,q,q);
SDL_RenderDrawLines(renderer,points,1);
}
And the compiler complains that I am not passing the correct type of argument for const(SDL_Point)* in points.
Error: function pointer SDL_RenderDrawLines (SDL_Renderer*, const(SDL_Point)*, int)
is not callable using argument types (SDL_Renderer*, const(SDL_Point[2u]), int)
I suspect this is a fundamental misunderstanding on my part so any help would be appreciated.
Arrays aren't implicitly castable to pointers in D. Instead, each array (both static and dynamic) has an intrinsic .ptr property that is a pointer to its first element.
Change your code to:
SDL_RenderDrawLines(renderer,points.ptr,1);
given that the call asks for a pointer and length, I feel it is safer to define you own wrapper:
SDL_RenderDrawLines(SDL_Renderer* rend, const SDL_Point[] points){
SDL_RenderDrawLines(rend,points.ptr,points.length);
}
(why it isn't defined I don't know, any performance hit from the extra function call is just a -inline away from being resolved)
This question already has answers here:
Why can one specify the size of an array in a function parameter?
(3 answers)
Closed 3 years ago.
This feels like a really stupid thing to ask, but I had someone taking a programming class ask me for some help on an assignment and I see this in their code (no comments on the Hungarian notation please):
void read_dictionary( string ar_dictionary[25], int & dictionary_size ) {...
Which, as mainly a C# programmer (I learned about C and C++ in college) I didn't even know you could do. I was always told, and have read since that you're supposed to have
void read_dictionary( string ar_dictionary[], int ar_dictionary_size, int & dictionary_size ) {...
I'm told that the professor gave them this and that it works, so what does declaring a fixed size array like that even mean? C++ has no native way of knowing the size of an array being passed to it (even if I think that might've been changed in the newest spec)
In a one dimensional array It has no significance and is ignored by the compiler. In a two or more dimensional array It can be useful and is used by the function as a way to determine the row length of the matrix(or multi dimensional array). for example :
int 2dArr(int arr[][10]){
return arr[1][2];
}
this function would know the address of arr[1][2] according to the specified length, and also the compiler should not accept different sizes of arrays for this function -
int arr[30][30];
2dArr(arr);
is not allowed and would be a compiler error(g++) :
error: cannot convert int (*)[30] to int (*)[10]
The 25 in the parameter declaration is ignored by the compiler. It's the same as if you'd written string ar_dictionary[]. This is because a parameter declaration of array type is implicitly adjusted to a pointer to the element's type.
So the following three function declarations are equivalent:
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
void read_dictionary(string ar_dictionary[], int& dictionary_size)
void read_dictionary(string *ar_dictionary, int& dictionary_size)
Even in the case of the first function, with the size of the array explicitly declared, sizeof(ar_dictionary) will return the same value as sizeof(void*).
See this sample on Codepad:
#include <string>
#include <iostream>
using namespace std;
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
{
cout << sizeof(ar_dictionary) << endl;
cout << sizeof(void*) << endl;
}
int main()
{
string test[25];
int dictionary_size = 25;
read_dictionary(test, dictionary_size);
return 0;
}
Output (the exact value is, of course, implementation-dependent; this is purely for example purposes):
4
4
I always though that passing fixed size C++ arrays was a "half baked" feature of C++. For example, ignored size matching or only being able to specify the first index size, etc... Until recently I learn this idiom:
template<size_t N1, size_t N2> // enable_if magic can be added as well
function(double(&m)[N1][N2]){
... do something with array m...knowing its size!
}
Reference: Can someone explain this template code that gives me the size of an array?
I'm building a comparator for an assignment, and I'm pulling my hair out because this seems to simple, but I can't figure it out.
This function is giving me trouble:
int compare(Word *a, Word *b)
{
string *aTerm = a->getString();
string *bTerm = b->getString();
return aTerm->compare(bTerm);
}
Word::getString returns a string*
Error:
In member function `virtual int CompWordByAlpha::compare(Word*, Word*)':
no matching function for call to...
...followed by a bunch of function definitions.
Any help?
You're comparing a string to a string pointer, and that's not valid. You want
return aTerm->compare(*bTerm);
You aren't getting the different uses of the * operator. The use of the * in "string* bTerm = b->getString()" means "bTerm is a pointer to a string". The use of the * inside of compare(*bTerm) means "take the value of the location pointed to by bTerm" instead of just using compare(bTerm) which simply attempts to compare the value of bTerm itself, which is a hex address.
This is also happening on the left side of that call:
aTerm->compare(*bTerm); //this statement
(*aTerm).compare(*bTerm); //is the same as this statement
The -> operator just reduces the amount of typing required.
P.S.: This kind of stuff you could have easily figured out from Google or your programming textbook. Although others may disagree, I don't feel that questions about completely basic syntax have any place on Stack Overflow.