Reputation: 4346
I delete my old question and reformulate the question here. Can I achieve following function using template instead?
#include <iostream>
using namespace std;
#define FUNC(T1, T2) do {cout<< T1.T2<<endl; } while(0);
struct ST{
double t1;
int t2;
double t3;
};
struct ST2{
int t1;
double h2;
};
int main()
{
ST st;
ST2 st2;
st.t1 = 1.1;
st.t2 = 0;
st.t3 = 3.3;
FUNC(st, t1);
FUNC(st, t2);
FUNC(st, t3);
FUNC(st2, h2);
}
Upvotes: 0
Views: 181
Reputation: 206689
I don't think you can do anything with that exact syntax. But you can get something close with member pointers and a function template:
template <typename T, typename Q>
void print(T& var, Q T::* mem)
{
cout << var.*mem << endl;
}
Use:
print(st, &ST::t1);
print(st, &ST::t2);
print(st2, &ST2::h2);
Note that st2.h2 is uninitialized in your example, so your code exhibits undefined behavior.
Upvotes: 3
Reputation: 106096
Short answer: No. But why would you want to? What's so special about that (
class variable,
member)
notation? You can obviously write a function that takes st.t1
instead of st, t1
- why are you trying to avoid that?
Long answer: Not usefully. t1
is not in scope at the point you're calling FUNC(st, t1)
... the current macro replaces it with st.t1
which can be found in the current scope. If you really really desparately wanted to hack something up, you'd have to put some kind of t1
, t2
, t3
, h2
etc. objects in scope that could be passed to a function and somehow encoded which field should be accessed. Having the local t1
et al be pointers to the member variables is an obvious choice. That would be pretty inconvenient, verbose and error-prone though: setting up all those extra variables just to support this indirection.
Upvotes: 4