Search code examples
c++functiontemplatesparameter-passinggeneric-programming

How do I pass a data member name as a parameter for use on another parameter?


Given a struct such as this:

struct Foo{
    std::string name;
    int value;
};

I'm looking for a way to pass both the instantiation of the type,
as well as the data member name,
each as separate arguments.

Although this is incorrect syntax, I think it helps illustrate what I am trying to accomplish:

template<typename MemberName>
void Print(Foo foo, MemberName member_name){
    std::cout << foo.member_name << '\n';  
}

int main(){

    Foo foo{"name",100}; //create instance

    Print(foo,.name);  //prints name
    Print(foo,.value); //prints 100
}

How can this be achieved in C++?

Additionally, I do not have access to modify the deceleration of the type.


Solution

  • You're probably looking for pointers to members:

    #include <string>
    #include <iostream>
    
    struct Foo{
      std::string name;
      int value;
    };
    
    template<typename MemberType>
    void Print(Foo foo, MemberType Foo::* member_name){
      std::cout << foo.*member_name << '\n';  
    }
    
    int main(){
    
      Foo foo{"name",100}; //create instance
    
      Print(foo, &Foo::name);  //prints name
      Print(foo, &Foo::value); //prints 100
    }
    

    Edit: of course, pointers to members aren't really common in c++ and in this specific case, just passing the actual member values like Steephen suggests is better (but maybe you want to use them in a more complicated case)