Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Trouble with the template Function derivedAction from the SFML-BOOK  (Read 2116 times)

0 Members and 1 Guest are viewing this topic.

Grundkurs

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
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 :-(
« Last Edit: November 27, 2014, 01:20:56 am by Grundkurs »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10819
    • View Profile
    • development blog
    • Email
AW: Trouble with the template Function derivedAction from the SFML-BOOK
« Reply #1 on: November 27, 2014, 08:18:31 am »
Note that the lambda is written with a [=] which means "[=] Capture any referenced variable by making a copy", thus all the variables in the scope where the lambda is written at is captured, including the fn object.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Trouble with the template Function derivedAction from the SFML-BOOK
« Reply #2 on: November 27, 2014, 08:39:37 am »
As for why you get the error about discarding qualifiers with your custom functor, that's because your functor's operator() is non-const.  Lambdas treat captured-by-value variables as const by default: https://stackoverflow.com/questions/5501959/why-does-c0xs-lambda-require-mutable-keyword-for-capture-by-value-by-defau

Grundkurs

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Re: Trouble with the template Function derivedAction from the SFML-BOOK
« Reply #3 on: November 27, 2014, 10:30:36 am »
Thanks to both of you, you saved my day! :-) Now everything makes sense. I got my my example to work and also noticed that i have overseen that the custom-functor from the SFML-Book example is const.