Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template function on struct members

Is there a way to code a single template function able to run on different members of a given struct ?

A wrong example would look like :

struct Foo
{
  int a, b;
}

template <MEMBER x> //which does not exist 
cout_member(Foo foo)
{
  cout << foo.x << endl;
}

int main()
{
  Foo foo; 
  cout_member<a>(foo);
  cout_member<b>(foo);
  return 0;
}

I imagined an answer based on a switch, but I then wondered if this switch would be tested on run-time (what I would like to avoid) or on compile-time ?

like image 764
valade aurélien Avatar asked Aug 14 '17 15:08

valade aurélien


People also ask

Can we use template in struct?

The entities of variable, function, struct, and class can have templates.

Can struct members be functions?

Member functions inside the structure: Structures in C cannot have member functions inside a structure but Structures in C++ can have member functions along with data members.

Can a non template class have a template member function?

A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.

Can a class member function template be virtual in C++?

A member function template cannot be virtual, and a member function template in a derived class cannot override a virtual member function from the base class.


1 Answers

As long as you want to pick up a data member from a set of data members having the same type, you can use a pointer to data member:

template <int Foo::*M>
void cout_member(Foo foo)
{
    std::cout << (foo.*M) << std::endl;
}

And use it as:

cout_member<&Foo::a>(foo);

If you want to indicate also the type, you can do this:

template <typename T, T Foo::*M>
void cout_member(Foo foo)
{
    std::cout << (foo.*M) << std::endl;
}

And use it as:

cout_member<int, &Foo::a>(foo);

Just out of curiosity, the second snippet would be even simpler in C++17:

template <auto M>
void cout_member(Foo foo)
{
    std::cout << (foo.*M) << std::endl;
}

See it up and running on wandbox;

like image 120
skypjack Avatar answered Sep 28 '22 06:09

skypjack