C++, passing struct features into function as a parameter












4















First of all, I would like to say this is the first question I am asking on stackOverflow, so I apologize if I am not clear enough.



My question regards referring parametrically to a struct feature inside a function. I work in C++.



What I really want to achieve is to be able to sort a vector of struct objects (or class objects) based on a specific struct feature, which is given as a parameter.
I also want to give the type of struct through a template, so some workarounds that deal with specific situations might not work in general.



I will show a simplistic example of what I mean.



Let's say, I have a struct called "human" with features: "age", "height", "weight".



Let's also assume that I have a vector of "human" objects called "mankind".



Here, let's say I want to make a function that can output to the screen each element's age, height or weight, depending on what I pass as a parameter.



The code below obviously doesn't work. I am asking for the proper way to do this.



struct human{
int age;
int height;
int weight;
};

void show(vector<human> &elements, int value){
for (int i=0; i<elements.size(); i++)
cout << elements[i].value << endl;
}

int main{
...
vector<human> mankind;
...
show(mankind, age);
show(mankind, height);
show(mankind, weight);
...
return 0;
}


I want to point out, that this example is a very simple case. Of course, I can make this work if I make separate functions for each feature or if I use a cheeky way, like passing a string "age" or "height" or "weight" as a parameter, checking it inside the function and having a completely separate case for each one.



However, such workarounds won't work in the general case of the problem, especially if I have many different types of structs (passed through a template T and vector< T > ) and features.










share|improve this question

























  • As for sorting: here

    – jrok
    Dec 28 '18 at 19:37











  • but i have to say that in c# it comes to easy with LINQ operations ;)

    – Alex Rivas
    Dec 28 '18 at 19:38
















4















First of all, I would like to say this is the first question I am asking on stackOverflow, so I apologize if I am not clear enough.



My question regards referring parametrically to a struct feature inside a function. I work in C++.



What I really want to achieve is to be able to sort a vector of struct objects (or class objects) based on a specific struct feature, which is given as a parameter.
I also want to give the type of struct through a template, so some workarounds that deal with specific situations might not work in general.



I will show a simplistic example of what I mean.



Let's say, I have a struct called "human" with features: "age", "height", "weight".



Let's also assume that I have a vector of "human" objects called "mankind".



Here, let's say I want to make a function that can output to the screen each element's age, height or weight, depending on what I pass as a parameter.



The code below obviously doesn't work. I am asking for the proper way to do this.



struct human{
int age;
int height;
int weight;
};

void show(vector<human> &elements, int value){
for (int i=0; i<elements.size(); i++)
cout << elements[i].value << endl;
}

int main{
...
vector<human> mankind;
...
show(mankind, age);
show(mankind, height);
show(mankind, weight);
...
return 0;
}


I want to point out, that this example is a very simple case. Of course, I can make this work if I make separate functions for each feature or if I use a cheeky way, like passing a string "age" or "height" or "weight" as a parameter, checking it inside the function and having a completely separate case for each one.



However, such workarounds won't work in the general case of the problem, especially if I have many different types of structs (passed through a template T and vector< T > ) and features.










share|improve this question

























  • As for sorting: here

    – jrok
    Dec 28 '18 at 19:37











  • but i have to say that in c# it comes to easy with LINQ operations ;)

    – Alex Rivas
    Dec 28 '18 at 19:38














4












4








4


1






First of all, I would like to say this is the first question I am asking on stackOverflow, so I apologize if I am not clear enough.



My question regards referring parametrically to a struct feature inside a function. I work in C++.



What I really want to achieve is to be able to sort a vector of struct objects (or class objects) based on a specific struct feature, which is given as a parameter.
I also want to give the type of struct through a template, so some workarounds that deal with specific situations might not work in general.



I will show a simplistic example of what I mean.



Let's say, I have a struct called "human" with features: "age", "height", "weight".



Let's also assume that I have a vector of "human" objects called "mankind".



Here, let's say I want to make a function that can output to the screen each element's age, height or weight, depending on what I pass as a parameter.



The code below obviously doesn't work. I am asking for the proper way to do this.



struct human{
int age;
int height;
int weight;
};

void show(vector<human> &elements, int value){
for (int i=0; i<elements.size(); i++)
cout << elements[i].value << endl;
}

int main{
...
vector<human> mankind;
...
show(mankind, age);
show(mankind, height);
show(mankind, weight);
...
return 0;
}


I want to point out, that this example is a very simple case. Of course, I can make this work if I make separate functions for each feature or if I use a cheeky way, like passing a string "age" or "height" or "weight" as a parameter, checking it inside the function and having a completely separate case for each one.



However, such workarounds won't work in the general case of the problem, especially if I have many different types of structs (passed through a template T and vector< T > ) and features.










share|improve this question
















First of all, I would like to say this is the first question I am asking on stackOverflow, so I apologize if I am not clear enough.



My question regards referring parametrically to a struct feature inside a function. I work in C++.



What I really want to achieve is to be able to sort a vector of struct objects (or class objects) based on a specific struct feature, which is given as a parameter.
I also want to give the type of struct through a template, so some workarounds that deal with specific situations might not work in general.



I will show a simplistic example of what I mean.



Let's say, I have a struct called "human" with features: "age", "height", "weight".



Let's also assume that I have a vector of "human" objects called "mankind".



Here, let's say I want to make a function that can output to the screen each element's age, height or weight, depending on what I pass as a parameter.



The code below obviously doesn't work. I am asking for the proper way to do this.



struct human{
int age;
int height;
int weight;
};

void show(vector<human> &elements, int value){
for (int i=0; i<elements.size(); i++)
cout << elements[i].value << endl;
}

int main{
...
vector<human> mankind;
...
show(mankind, age);
show(mankind, height);
show(mankind, weight);
...
return 0;
}


I want to point out, that this example is a very simple case. Of course, I can make this work if I make separate functions for each feature or if I use a cheeky way, like passing a string "age" or "height" or "weight" as a parameter, checking it inside the function and having a completely separate case for each one.



However, such workarounds won't work in the general case of the problem, especially if I have many different types of structs (passed through a template T and vector< T > ) and features.







c++ struct parameters






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 28 '18 at 19:44









NathanOliver

88.9k15120186




88.9k15120186










asked Dec 28 '18 at 19:30









New GuyNew Guy

211




211













  • As for sorting: here

    – jrok
    Dec 28 '18 at 19:37











  • but i have to say that in c# it comes to easy with LINQ operations ;)

    – Alex Rivas
    Dec 28 '18 at 19:38



















  • As for sorting: here

    – jrok
    Dec 28 '18 at 19:37











  • but i have to say that in c# it comes to easy with LINQ operations ;)

    – Alex Rivas
    Dec 28 '18 at 19:38

















As for sorting: here

– jrok
Dec 28 '18 at 19:37





As for sorting: here

– jrok
Dec 28 '18 at 19:37













but i have to say that in c# it comes to easy with LINQ operations ;)

– Alex Rivas
Dec 28 '18 at 19:38





but i have to say that in c# it comes to easy with LINQ operations ;)

– Alex Rivas
Dec 28 '18 at 19:38












3 Answers
3






active

oldest

votes


















3














One way to do this is to use pointers-to-members, a C++ feature that lets you create pointers that refer to specific fields of a struct or class.



The syntax here might look a little scary, but it's actually not so bad. For example, here's how you'd get a pointer to the height field of your human struct:



int human::* ptr = &human::height;


Here, the syntax int human::* ptr means




  1. that it's a pointer to something inside the human type;

  2. specifically, it's a pointer to an int data member; and

  3. that data member is the height field.


Once you have this pointer, you can combine it with a human struct to isolate out just that member like this:



human agatha;
cout << agatha.*ptr << endl;


Here, the .* operator means "pull up the field pointed at by ptr.



In your case, you might put things together like this:



void show(vector<human> &elements, int human::* value){
for (int i=0; i<elements.size(); i++)
cout << elements[i].*value << endl;
}

int main{
...
vector<human> mankind;
...
show(mankind, &human::age);
show(mankind, &human::height);
show(mankind, &human::weight);
...
return 0;
}





share|improve this answer
























  • I concur that a pointer to a member function is the C++ way of doing things here.

    – user3344003
    Dec 28 '18 at 19:48











  • Thank you! This is exactly what I needed. Works perfectly.

    – New Guy
    Dec 28 '18 at 19:51



















2














I prefer the lambda approach to this problem. If the function doesn't know what will be printed, just the calling code, then you can pass a lambda to the function that contains the code of what to print. That way you can make the function completely generic like



template <typename T, typename Func>
void show(vector<T> const& elements, Func f){
for (auto const& e : elements)
cout << f(e)<< endl;
}


and then you would call it like



show(mankind, (auto const& e){return e.age;});
show(mankind, (auto const& e){return e.height;});
show(mankind, (auto const& e){return e.weight;});




If show needs to show this member in order then you can even leverage the lambda in you call to std::sort like



template <typename T, typename Func>
void show(vector<T>& elements, Func f){
std::sort(elements.begin(), elements.end(), [=](auto const& lhs, auto const& rhs){return f(lhs) < f(rhs);});
for (auto const& e : elements)
cout << f(e)<< endl;
}


So the element to print is used to the sort vector and to print the element.






share|improve this answer

































    1














    Here are some thoughts on and improvements to the other answers:



    1) If your struct contains members of different types, you'll have to overload all functions using the pointer to member for each of the types. Or you'd have to use a template like:



    #include <vector>
    #include <iostream>

    struct human{
    int age;
    int height;
    float weight;
    };

    template<typename T>
    void show(std::vector<human> &elements, T human::* value){
    for (int i=0; i<elements.size(); i++)
    std::cout << elements[i].*value << std::endl;
    }


    2) I find the lambda approach more flexible, as it allows you to use combined features which could prove useful in real-world applications:



    // body-mass-index
    auto bmi = (const human& e) { return e.height / (e.weight * e.weight); };

    show(mankind, bmi);


    3) Also, the lambda approach allows you to manipulate features for sorting, filtering etc:



    auto inverse = (auto func) {
    return [=](const human& e) { return -func(e);};
    };

    template<typename T, typename Func>
    void sort(std::vector<T> &elements, Func f) {
    std::sort(elements.begin(), elements.end(), [=](auto const &lhs, auto const &rhs) { return f(lhs) < f(rhs); });
    }

    sort(mankind, inverse(bmi));


    4) The lambda approach allows you to use you exactly the specified syntax on the call site, if you put the lambdas into global variables (see the bmi example above).



    5) Starting with C++14 we have generic lambdas, so you can reuse the lambdas for multiple different types of structs.






    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53963447%2fc-passing-struct-features-into-function-as-a-parameter%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      3














      One way to do this is to use pointers-to-members, a C++ feature that lets you create pointers that refer to specific fields of a struct or class.



      The syntax here might look a little scary, but it's actually not so bad. For example, here's how you'd get a pointer to the height field of your human struct:



      int human::* ptr = &human::height;


      Here, the syntax int human::* ptr means




      1. that it's a pointer to something inside the human type;

      2. specifically, it's a pointer to an int data member; and

      3. that data member is the height field.


      Once you have this pointer, you can combine it with a human struct to isolate out just that member like this:



      human agatha;
      cout << agatha.*ptr << endl;


      Here, the .* operator means "pull up the field pointed at by ptr.



      In your case, you might put things together like this:



      void show(vector<human> &elements, int human::* value){
      for (int i=0; i<elements.size(); i++)
      cout << elements[i].*value << endl;
      }

      int main{
      ...
      vector<human> mankind;
      ...
      show(mankind, &human::age);
      show(mankind, &human::height);
      show(mankind, &human::weight);
      ...
      return 0;
      }





      share|improve this answer
























      • I concur that a pointer to a member function is the C++ way of doing things here.

        – user3344003
        Dec 28 '18 at 19:48











      • Thank you! This is exactly what I needed. Works perfectly.

        – New Guy
        Dec 28 '18 at 19:51
















      3














      One way to do this is to use pointers-to-members, a C++ feature that lets you create pointers that refer to specific fields of a struct or class.



      The syntax here might look a little scary, but it's actually not so bad. For example, here's how you'd get a pointer to the height field of your human struct:



      int human::* ptr = &human::height;


      Here, the syntax int human::* ptr means




      1. that it's a pointer to something inside the human type;

      2. specifically, it's a pointer to an int data member; and

      3. that data member is the height field.


      Once you have this pointer, you can combine it with a human struct to isolate out just that member like this:



      human agatha;
      cout << agatha.*ptr << endl;


      Here, the .* operator means "pull up the field pointed at by ptr.



      In your case, you might put things together like this:



      void show(vector<human> &elements, int human::* value){
      for (int i=0; i<elements.size(); i++)
      cout << elements[i].*value << endl;
      }

      int main{
      ...
      vector<human> mankind;
      ...
      show(mankind, &human::age);
      show(mankind, &human::height);
      show(mankind, &human::weight);
      ...
      return 0;
      }





      share|improve this answer
























      • I concur that a pointer to a member function is the C++ way of doing things here.

        – user3344003
        Dec 28 '18 at 19:48











      • Thank you! This is exactly what I needed. Works perfectly.

        – New Guy
        Dec 28 '18 at 19:51














      3












      3








      3







      One way to do this is to use pointers-to-members, a C++ feature that lets you create pointers that refer to specific fields of a struct or class.



      The syntax here might look a little scary, but it's actually not so bad. For example, here's how you'd get a pointer to the height field of your human struct:



      int human::* ptr = &human::height;


      Here, the syntax int human::* ptr means




      1. that it's a pointer to something inside the human type;

      2. specifically, it's a pointer to an int data member; and

      3. that data member is the height field.


      Once you have this pointer, you can combine it with a human struct to isolate out just that member like this:



      human agatha;
      cout << agatha.*ptr << endl;


      Here, the .* operator means "pull up the field pointed at by ptr.



      In your case, you might put things together like this:



      void show(vector<human> &elements, int human::* value){
      for (int i=0; i<elements.size(); i++)
      cout << elements[i].*value << endl;
      }

      int main{
      ...
      vector<human> mankind;
      ...
      show(mankind, &human::age);
      show(mankind, &human::height);
      show(mankind, &human::weight);
      ...
      return 0;
      }





      share|improve this answer













      One way to do this is to use pointers-to-members, a C++ feature that lets you create pointers that refer to specific fields of a struct or class.



      The syntax here might look a little scary, but it's actually not so bad. For example, here's how you'd get a pointer to the height field of your human struct:



      int human::* ptr = &human::height;


      Here, the syntax int human::* ptr means




      1. that it's a pointer to something inside the human type;

      2. specifically, it's a pointer to an int data member; and

      3. that data member is the height field.


      Once you have this pointer, you can combine it with a human struct to isolate out just that member like this:



      human agatha;
      cout << agatha.*ptr << endl;


      Here, the .* operator means "pull up the field pointed at by ptr.



      In your case, you might put things together like this:



      void show(vector<human> &elements, int human::* value){
      for (int i=0; i<elements.size(); i++)
      cout << elements[i].*value << endl;
      }

      int main{
      ...
      vector<human> mankind;
      ...
      show(mankind, &human::age);
      show(mankind, &human::height);
      show(mankind, &human::weight);
      ...
      return 0;
      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Dec 28 '18 at 19:38









      templatetypedeftemplatetypedef

      262k68666891




      262k68666891













      • I concur that a pointer to a member function is the C++ way of doing things here.

        – user3344003
        Dec 28 '18 at 19:48











      • Thank you! This is exactly what I needed. Works perfectly.

        – New Guy
        Dec 28 '18 at 19:51



















      • I concur that a pointer to a member function is the C++ way of doing things here.

        – user3344003
        Dec 28 '18 at 19:48











      • Thank you! This is exactly what I needed. Works perfectly.

        – New Guy
        Dec 28 '18 at 19:51

















      I concur that a pointer to a member function is the C++ way of doing things here.

      – user3344003
      Dec 28 '18 at 19:48





      I concur that a pointer to a member function is the C++ way of doing things here.

      – user3344003
      Dec 28 '18 at 19:48













      Thank you! This is exactly what I needed. Works perfectly.

      – New Guy
      Dec 28 '18 at 19:51





      Thank you! This is exactly what I needed. Works perfectly.

      – New Guy
      Dec 28 '18 at 19:51













      2














      I prefer the lambda approach to this problem. If the function doesn't know what will be printed, just the calling code, then you can pass a lambda to the function that contains the code of what to print. That way you can make the function completely generic like



      template <typename T, typename Func>
      void show(vector<T> const& elements, Func f){
      for (auto const& e : elements)
      cout << f(e)<< endl;
      }


      and then you would call it like



      show(mankind, (auto const& e){return e.age;});
      show(mankind, (auto const& e){return e.height;});
      show(mankind, (auto const& e){return e.weight;});




      If show needs to show this member in order then you can even leverage the lambda in you call to std::sort like



      template <typename T, typename Func>
      void show(vector<T>& elements, Func f){
      std::sort(elements.begin(), elements.end(), [=](auto const& lhs, auto const& rhs){return f(lhs) < f(rhs);});
      for (auto const& e : elements)
      cout << f(e)<< endl;
      }


      So the element to print is used to the sort vector and to print the element.






      share|improve this answer






























        2














        I prefer the lambda approach to this problem. If the function doesn't know what will be printed, just the calling code, then you can pass a lambda to the function that contains the code of what to print. That way you can make the function completely generic like



        template <typename T, typename Func>
        void show(vector<T> const& elements, Func f){
        for (auto const& e : elements)
        cout << f(e)<< endl;
        }


        and then you would call it like



        show(mankind, (auto const& e){return e.age;});
        show(mankind, (auto const& e){return e.height;});
        show(mankind, (auto const& e){return e.weight;});




        If show needs to show this member in order then you can even leverage the lambda in you call to std::sort like



        template <typename T, typename Func>
        void show(vector<T>& elements, Func f){
        std::sort(elements.begin(), elements.end(), [=](auto const& lhs, auto const& rhs){return f(lhs) < f(rhs);});
        for (auto const& e : elements)
        cout << f(e)<< endl;
        }


        So the element to print is used to the sort vector and to print the element.






        share|improve this answer




























          2












          2








          2







          I prefer the lambda approach to this problem. If the function doesn't know what will be printed, just the calling code, then you can pass a lambda to the function that contains the code of what to print. That way you can make the function completely generic like



          template <typename T, typename Func>
          void show(vector<T> const& elements, Func f){
          for (auto const& e : elements)
          cout << f(e)<< endl;
          }


          and then you would call it like



          show(mankind, (auto const& e){return e.age;});
          show(mankind, (auto const& e){return e.height;});
          show(mankind, (auto const& e){return e.weight;});




          If show needs to show this member in order then you can even leverage the lambda in you call to std::sort like



          template <typename T, typename Func>
          void show(vector<T>& elements, Func f){
          std::sort(elements.begin(), elements.end(), [=](auto const& lhs, auto const& rhs){return f(lhs) < f(rhs);});
          for (auto const& e : elements)
          cout << f(e)<< endl;
          }


          So the element to print is used to the sort vector and to print the element.






          share|improve this answer















          I prefer the lambda approach to this problem. If the function doesn't know what will be printed, just the calling code, then you can pass a lambda to the function that contains the code of what to print. That way you can make the function completely generic like



          template <typename T, typename Func>
          void show(vector<T> const& elements, Func f){
          for (auto const& e : elements)
          cout << f(e)<< endl;
          }


          and then you would call it like



          show(mankind, (auto const& e){return e.age;});
          show(mankind, (auto const& e){return e.height;});
          show(mankind, (auto const& e){return e.weight;});




          If show needs to show this member in order then you can even leverage the lambda in you call to std::sort like



          template <typename T, typename Func>
          void show(vector<T>& elements, Func f){
          std::sort(elements.begin(), elements.end(), [=](auto const& lhs, auto const& rhs){return f(lhs) < f(rhs);});
          for (auto const& e : elements)
          cout << f(e)<< endl;
          }


          So the element to print is used to the sort vector and to print the element.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 28 '18 at 19:48

























          answered Dec 28 '18 at 19:38









          NathanOliverNathanOliver

          88.9k15120186




          88.9k15120186























              1














              Here are some thoughts on and improvements to the other answers:



              1) If your struct contains members of different types, you'll have to overload all functions using the pointer to member for each of the types. Or you'd have to use a template like:



              #include <vector>
              #include <iostream>

              struct human{
              int age;
              int height;
              float weight;
              };

              template<typename T>
              void show(std::vector<human> &elements, T human::* value){
              for (int i=0; i<elements.size(); i++)
              std::cout << elements[i].*value << std::endl;
              }


              2) I find the lambda approach more flexible, as it allows you to use combined features which could prove useful in real-world applications:



              // body-mass-index
              auto bmi = (const human& e) { return e.height / (e.weight * e.weight); };

              show(mankind, bmi);


              3) Also, the lambda approach allows you to manipulate features for sorting, filtering etc:



              auto inverse = (auto func) {
              return [=](const human& e) { return -func(e);};
              };

              template<typename T, typename Func>
              void sort(std::vector<T> &elements, Func f) {
              std::sort(elements.begin(), elements.end(), [=](auto const &lhs, auto const &rhs) { return f(lhs) < f(rhs); });
              }

              sort(mankind, inverse(bmi));


              4) The lambda approach allows you to use you exactly the specified syntax on the call site, if you put the lambdas into global variables (see the bmi example above).



              5) Starting with C++14 we have generic lambdas, so you can reuse the lambdas for multiple different types of structs.






              share|improve this answer






























                1














                Here are some thoughts on and improvements to the other answers:



                1) If your struct contains members of different types, you'll have to overload all functions using the pointer to member for each of the types. Or you'd have to use a template like:



                #include <vector>
                #include <iostream>

                struct human{
                int age;
                int height;
                float weight;
                };

                template<typename T>
                void show(std::vector<human> &elements, T human::* value){
                for (int i=0; i<elements.size(); i++)
                std::cout << elements[i].*value << std::endl;
                }


                2) I find the lambda approach more flexible, as it allows you to use combined features which could prove useful in real-world applications:



                // body-mass-index
                auto bmi = (const human& e) { return e.height / (e.weight * e.weight); };

                show(mankind, bmi);


                3) Also, the lambda approach allows you to manipulate features for sorting, filtering etc:



                auto inverse = (auto func) {
                return [=](const human& e) { return -func(e);};
                };

                template<typename T, typename Func>
                void sort(std::vector<T> &elements, Func f) {
                std::sort(elements.begin(), elements.end(), [=](auto const &lhs, auto const &rhs) { return f(lhs) < f(rhs); });
                }

                sort(mankind, inverse(bmi));


                4) The lambda approach allows you to use you exactly the specified syntax on the call site, if you put the lambdas into global variables (see the bmi example above).



                5) Starting with C++14 we have generic lambdas, so you can reuse the lambdas for multiple different types of structs.






                share|improve this answer




























                  1












                  1








                  1







                  Here are some thoughts on and improvements to the other answers:



                  1) If your struct contains members of different types, you'll have to overload all functions using the pointer to member for each of the types. Or you'd have to use a template like:



                  #include <vector>
                  #include <iostream>

                  struct human{
                  int age;
                  int height;
                  float weight;
                  };

                  template<typename T>
                  void show(std::vector<human> &elements, T human::* value){
                  for (int i=0; i<elements.size(); i++)
                  std::cout << elements[i].*value << std::endl;
                  }


                  2) I find the lambda approach more flexible, as it allows you to use combined features which could prove useful in real-world applications:



                  // body-mass-index
                  auto bmi = (const human& e) { return e.height / (e.weight * e.weight); };

                  show(mankind, bmi);


                  3) Also, the lambda approach allows you to manipulate features for sorting, filtering etc:



                  auto inverse = (auto func) {
                  return [=](const human& e) { return -func(e);};
                  };

                  template<typename T, typename Func>
                  void sort(std::vector<T> &elements, Func f) {
                  std::sort(elements.begin(), elements.end(), [=](auto const &lhs, auto const &rhs) { return f(lhs) < f(rhs); });
                  }

                  sort(mankind, inverse(bmi));


                  4) The lambda approach allows you to use you exactly the specified syntax on the call site, if you put the lambdas into global variables (see the bmi example above).



                  5) Starting with C++14 we have generic lambdas, so you can reuse the lambdas for multiple different types of structs.






                  share|improve this answer















                  Here are some thoughts on and improvements to the other answers:



                  1) If your struct contains members of different types, you'll have to overload all functions using the pointer to member for each of the types. Or you'd have to use a template like:



                  #include <vector>
                  #include <iostream>

                  struct human{
                  int age;
                  int height;
                  float weight;
                  };

                  template<typename T>
                  void show(std::vector<human> &elements, T human::* value){
                  for (int i=0; i<elements.size(); i++)
                  std::cout << elements[i].*value << std::endl;
                  }


                  2) I find the lambda approach more flexible, as it allows you to use combined features which could prove useful in real-world applications:



                  // body-mass-index
                  auto bmi = (const human& e) { return e.height / (e.weight * e.weight); };

                  show(mankind, bmi);


                  3) Also, the lambda approach allows you to manipulate features for sorting, filtering etc:



                  auto inverse = (auto func) {
                  return [=](const human& e) { return -func(e);};
                  };

                  template<typename T, typename Func>
                  void sort(std::vector<T> &elements, Func f) {
                  std::sort(elements.begin(), elements.end(), [=](auto const &lhs, auto const &rhs) { return f(lhs) < f(rhs); });
                  }

                  sort(mankind, inverse(bmi));


                  4) The lambda approach allows you to use you exactly the specified syntax on the call site, if you put the lambdas into global variables (see the bmi example above).



                  5) Starting with C++14 we have generic lambdas, so you can reuse the lambdas for multiple different types of structs.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Dec 28 '18 at 22:37

























                  answered Dec 28 '18 at 22:30









                  florestanflorestan

                  50629




                  50629






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53963447%2fc-passing-struct-features-into-function-as-a-parameter%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Monofisismo

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas