3

To be short, I want to achieve something like "templatize" the operation of "getting an attribute of a object" as a generalized template function, like the function foo below.

template <
    typename T, 
    // something like
    "attribute" obj // or T::obj
>
"sth refer to type of obj" foo(T t)
{
    return t.obj; 
}

What I hope to achieve is, with any simple struct/class like

struct A
{
    int b; 
    type_of_c c; 
    ...
} a; // for any class/struct A with (non-function) attribute b in any type

foo<A, A::b>(a) may return a.b, and foo<A, A::c>(a) may return a.c.

So my question is, how can I express T::obj to set the information of "specifying attribute obj of class T" as the parameter of template?

Some limitations in my programming:

  • Methods that unfriendly to compile and IDE auto-hints are not encouraged. e.g. sending attribute name in form of string instead of attribute itself, or involving macro.
  • Add type of T::obj to the template is acceptable, but not encouraged.
  • Tricks in any version of c++ is acceptable. Using newly published versions like C++20 is definitely ok.
  • The solution is expected to work also for class template, if possible.
2
  • 2
    Pointer-to-member. template <typename T, typename U, U T::*ptm>. Demo With a sufficiently recent compiler, can be further simplified to this Commented Aug 12, 2024 at 16:39
  • std::bind_front(&A::b) will give you a functor you can call with an A. Is this enough? Commented Aug 12, 2024 at 20:16

1 Answer 1

1

You can make use of pointer to members. To avoid having three template parameter, you can also make use of template argument deduction as shown below.

template < typename T, typename U>
U foo2(U (T::*obj), T t)
{
    return (t.*obj); 
}
int main()
{
    std::cout << foo2(&A::b, a);
}

Working demo


Solution 2

If you're okay with passing three template argument you can also do:

template < typename T, typename U, U (T::*obj)>
U foo(T t)
{
    return (t.*obj); 
}
int main()
{
    std::cout << foo<A, int, &A::b>(a);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Marvelous! That's just what I want. Great Thanks! I've also thought about pointers but I didn't know it can be used like this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.