Template function for structure elements

Is there a way to encode a single template function that can work on different members of a given struct ?

An example incorrect would look like this:

 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 presented the answer based on the switch, but then I wondered if that switch would be checked at runtime (which I would like to avoid) or at compile time?

+5
source share
2 answers

While you want to get a data element from a set of data elements of the same type, you can use a pointer to the data element:

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

And use it like:

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

If you want to specify the type as well, you can do this:

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

And use it like:

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

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

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

Take a look at wandbox ;

+10
source

You can use std::mem_fn so you don't even have to worry: (unchecked)

 template < typename Fun, typename ... Params > void print(Fun f, Params && ... p) { std::cout << f(std::forward<Params>(p)...) << "\n"; } print(std::mem_fn(&Obj::fun), Obj()); 

Since you use streams, you probably don't care ... but this should add a little to zero overhead just by writing cout << obj.fun() .

Edit: mem_fn also works with data. Creates a callable that returns a reference to a value that you can use: int x = mem_fn(&pair<int,char>::first)(my_pair);

+1
source

Source: https://habr.com/ru/post/1270860/


All Articles