I wanted to know what I might be doing wrong here. This is my code sample. Its just a rough code sample depicting the use of function pointers.In the following example the fuunction pointer takes in a parameter.However that parameter was already assigned during function pointer assignment.Now in order to invoke the function pointer i still need to provide a parameter value although that value is nver used (unless i used std::placeholder). My question is how do i invoke a function pointer that requires a parameter and whose parameter has already been assigned without passing in a parameter.
#include <iostream>
#include <functional>
using namespace std;
std::function<std::string(std::string)> fptr;
std::string foo()
{
return fptr(); //--->statement A - I need to invoke this funct ptr without passing a parameter as a parameter has already been assigned in statement B
}
std::string bar(std::string p)
{
return p;
}
int main()
{
fptr = std::bind(&bar,"Hello"); --->statement B
std::cout << foo();
}
Notice in std::bind I did not use any placeholders and "Hello" is the parameter to the function bar. My question is why does
return fptr();
not work. If i do the following
return fptr("Bye");
It works and returns "Hello" . (No point of passing parameter during fptr call) Why does it not work without a parameter ?
The result of std::bind allows you passing more arguments than it needed, and ignore these extra arguments. In your case, std::bind(&bar, "Hello") can be called without arguments, or, declared by fptr, with one std::string argument.
The solution to your problem is easy, just change the type of fptr to std::function<std::string()>, which accept no arguments and return a string.
Related
So, I have this template class and its specialization.
#include <iostream>
using namespace std;
template<bool> struct CompileTimeChecker{
CompileTimeChecker(...); //constructor, can accept any number of parameters;
};
//specialized template definition
template<> struct CompileTimeChecker<false> {
//default constructor, body empty
};
Case 1:
In the main function I am defining a local class called ErrorA. When I create a temporary of CompileTimeChecker<false> with temporary object of ErrorA fed as an initializer, the compiler is not detecting any error.
int main()
{
class ErrorA {};
CompileTimeChecker<false>(ErrorA()); //Case 1;
CompileTimeChecker<false>(int()); //Case 2;
return 0;
}
Case 2:
Next I feed it with temporary object of type int, and suddenly the compiler recognizes the issue (there is no constructor that takes args in the specialized template CompileTimeChecker<false>)
main.cpp:30:36: error: no matching function for call to ‘CompileTimeChecker::CompileTimeChecker(int)’ CompileTimeChecker<false>(int());
main.cpp:21:23: note: candidate: constexpr CompileTimeChecker::CompileTimeChecker()
template<> struct CompileTimeChecker<false> {
^~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:21:23: note: candidate expects 0 arguments, 1 provided
Why does it not recognize the issue in case 1?
CompileTimeChecker<false>(ErrorA());
does not create a temporary of type CompileTimeChecker<false>, passing a temporary ErrorA() to its constructor. Rather, it declares a function named ErrorA, taking no parameters and returning CompileTimeChecker<false> . See also: most vexing parse.
On the other hand, CompileTimeChecker<false>(int()); cannot be parsed as a declaration, so it does unambiguously create a temporary of type CompileTimeChecker<false>.
The easiest way out is to use braces in place of parens to indicate initialization:
CompileTimeChecker<false>{ErrorA{}};
This is part of an assignment, I am stuck at this instruction:
Sort your randomly generated pool of schedules.
Use std::stable_sort,
passing in an object of type schedule_compare as the custom comparison
operator.
UPDATE: I was checking cppreference stable_srot(), see method definition below:
void stable_sort ( RandomAccessIterator first, RandomAccessIterator
last,Compare comp );
, and it seems from what I understood is that you can only pass functions to the last argument (Compare comp) of the stable_sort() i.e:
However, in the instructions, it says that you need to pass an object of type schedule_compare. How is this possible ?
This is my code below:
struct schedule_compare
{
explicit schedule_compare(runtime_matrix const& m)
: matrix_{m} { }
bool operator()(schedule const& obj1, schedule const& obj2) {
if (obj1.score > obj2.score)
return true;
else
return false;
}
private:
runtime_matrix const& matrix_;
};
auto populate_gene_pool(runtime_matrix const& matrix,
size_t const pool_size, random_generator& gen)
{
std::vector<schedule> v_schedule;
v_schedule.reserve(pool_size);
std::uniform_int_distribution<size_t> dis(0, matrix.machines() - 1);
// 4. Sort your randomly generated pool of schedules. Use
// std::stable_sort, passing in an object of type
// schedule_compare as the custom comparison operator.
std::stable_sort(begin(v_schedule), end(v_schedule), ???)
return; v_schedule;
}
For algorithm functions that accepts a "function" (like std::stable_sort) you can pass anything that can be called as a function.
For example a pointer to a global, namespace or static member function. Or you can pass a function-like object instance (i.e. an instance of a class that has a function call operator), also known as a functor object.
This is simply done by creating a temporary object, and passing it to the std::stable_sort (in your case):
std::stable_sort(begin(v_schedule), end(v_schedule), schedule_compare(matrix));
Since the schedule_compare structure have a function call operator (the operator() member function) it can generally be treated like any other function, including being "called".
#include <iostream>
#include <functional>
using namespace std;
std::function<void(void)> makeLambda(int param)
{
return [¶m](){cout << param << endl;};
}
int main()
{
auto callback = makeLambda(5);
callback();
}
Based on lambda description as following, it looks the program will cause an undefined behavior because when callback is invoked, the captured var, function parameter, is out-of-scope. But I see it always can print 5.
My g++ version is gcc-4.9.1.
Dangling references
If an entity is captured by reference, implicitly or explicitly, and
the function call operator of the closure object is invoked after the
entity's lifetime has ended, undefined behavior occurs. The C++
closures do not extend the lifetimes of the captured references.
Same applies to the lifetime of the object pointed to by the captured
this pointer.
Why can it work?
As you note, this is undefined behaviour. Anything can happen, including appearing to work. If you switch compiler, change flags, forget to do the dishes, or get up an hour later, you could get completely different results.
As an example, Clang prints 32767 for some version and set of flags.
In the following code I created a char pointer and a FILE pointer, and tried to pass both to a function "by value of course".
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void move(char *s){
++s;
}
void moveF(FILE *f){
getc(f);
}
int main(){
char *s = malloc(64);
strcpy(s,"123456");
puts(s);
move(s);
puts(s);
//~~~~~~~~~~
FILE *f = fopen("file1","r");
printf("%d\n",(int)ftell(f));
moveF(f);
printf("%d\n",(int)ftell(f));
}
I know that passing by value means that the parameter is a copy of the original variable in the calling function, That's why you can notice that after passing the char pointer, it's value in main function was not changed at all, but what is weird is that passing a FILE pointer and changing the value of the parameter caused changing the value of the variable inside main function.
Can someone please explain this behavior.
Thanks.
Passing a pointer to an object is the same as passing the object by reference. Hence, you’re passing a FILE structure by reference. The pointers in either function point to the same object in memory, so either can modify the object and see the others changes.
I would like to achieve the following
#include <iostream>
unsigned foo(int i) {return i;};
unsigned bar(unsigned(*p)()) {/*Do important work*/return p();};
int main(void){
int integer = 42;
auto lambda = [integer] () -> unsigned {return foo(integer);};
unsigned number = bar(lambda);
std::cout << number << std::endl;
}
That is, bar is expecting a pointer to function with no arguments and returning unsigned. I can easily write a wrapper unsigned baz() {return foo(42);};and pass that one to bar(), but this has two drawbacks
it's a separate function, while I would prefer to construct the wrapper inline
I have to write a new wrapper for each expected value of `integer.
The idea is that bar() is doing some work, in the process invoking the function, that was passed to it. I have a suitable function, but it has an extra argument. That extra argument, however, is known at the point of passing the function to bar().
Is there a way to pull this off, or should I forget this approach and use templates? I have control over changing the interface (e.g. change the function pointer argument to std::function).`