I have questions regarding functions, more specific on function signatures and how to pass them. I might be a trivial or even stupid question, but I couldn't find a satisfying answer yet.
Please consider this example which uses a std::unique_ptr
to manage a file pointer:
#include <iostream>
#include <memory>
void func1(FILE* f)
{
std::cout << "func1 called" << std::endl;
fclose(f);
}
int main()
{
FILE* f = fopen("testfile.txt", "w");
if(f)
{
std::unique_ptr<FILE, void(*)(FILE*)> fptr(f, &func1);
}
return 0;
}
This kind of smart pointer needs a functions signature as second template argument (shared_ptr
does not for some odd reason). My current understanding of interpreting the signature here is
void () (FILE) is a pointer to a function returning nothing (void) and a filepointer as argument.
As a result, the user has to pass the address of the desired function with the address operator. At this point, a few questions arise:
1.) Removal of the address operator works just as well, no compiler warning is thrown, code works. Shouldn't this be an error/warning?
2.) If I use a reference to a function (e.g. unique_ptr<FILE, void(&)(FILE*)>(f, func1)
) it works as expected, so is this a superior way to pass a function as it is unambiguous?
3.) Removing the middle specifier altogether (e.g. unique_ptr<FILE, void()(FILE*)>(f, func1)
) causes compiler errors, so is passing a function by value impossible in general? (if it is, then it would make sense to overload the version in 1. by implicitly converting the function to a function pointer)
CodePudding user response:
Function name is the always address of function (pointer to the function). If you want to use something else you can use some wrapper, e.g. std::function:
#include <iostream>
#include <memory>
#include <functional>
class Closer {
public:
void operator ()(FILE *f) {
std::cout << "func1 called" << std::endl;
fclose(f);
}
};
int main()
{
FILE* f = fopen("testfile.txt", "w");
if(f)
{
std::unique_ptr<FILE, std::function<void(FILE*)>> fptr(f, Closer());
}
return 0;
}
Lambda in that case is anonymous functional object.