Hey there,
i have some trouble understanding a certain template function used in the Codebase of the SFML Book. Its basically a straight c++ related question, however because its from the Codebase of the SFML Book i guess there is a high chance that here might be someone who have already seen this snipped of code and it may be appropriate to ask here about it:
1. template <typename GameObject, typename Function>
2. std::function<void(SceneNode&, sf::Time)> derivedAction(Function fn)
3. {
4. return [=] (SceneNode& node, sf::Time dt)
5. {
6. // Check if cast is safe
7. assert(dynamic_cast<GameObject*>(&node) != nullptr);
8.
9. // Downcast node and invoke function on it
10. fn(static_cast<GameObject&>(node), dt);
11. };
12.}
I was wondering why the return-Statement can use the "fn" Function-Object (line 10) passed by the Parameter of the template function (line 2) because when the lambda (line 4) is assigned to a std::function<...> object, that object itself would not be able to use the passed Function Object (line 2), because its not part of the lambda.
Because i had trouble understanding that, i tried to implement a more simple code example to see how this works.
//functor
class add2{
int number;
public:
add2(int num) : number{num}{}
void operator()(int i){
std::cout << i + number << "\n";
}
};
template<typename Function>
std::function<void(int)> getFunction(Function fn){
return [=] (int number)
{
fn(number);
};
}
template<typename Function>
std::function<void(int)> getFunction(){
return [=] (int number)
{
Function fn{2};
fn(number);
};
}
int main(){
//std::function<void(int)> function = getFunction<add2>(add2{2}); //error
//std::function<void(int)> function = getFunction<add2>(); //works
std::vector<int> numbers ={5,6,7,8};
for_each(numbers.begin(), numbers.end(), function);
return 0;
}
The first template function breaks with the message "error: passing 'const add2' as 'this' argument of 'void add::operator()(int)' discards qualifiers [-fpermissive]". The second one works fine as expected. My guess why at least the second function works is, because i create the Functor-Object within the return statement of the lambda the method that gets assigned to that lambda can access the Functor-Object because its part of the lambda. It just makes no sense to me that the code from the book works but my first template function does not :-(