Reputation: 38939
OK so I was cooking up an answer here which has more detail (and a better alternative.) But I realized I'd made a couple template functions which had a lot of redudancy. Given:
template<typename T>
struct Parent {};
struct Child : Parent<int> {};
I wrote the following template functions for getting the appropriate Parent
pointer:
namespace details {
template<typename T>
Parent<T>* make_parent(Parent<T>* param) { return param; }
}
template<typename T>
auto make_parent(T& param) -> decltype(details::make_parent(¶m)) { return details::make_parent(¶m); }
There seems to be a lot of repetition in there. But I can't figure out how to make it cleaner. Can I combine this into a single function without it looking like a nightmare?
EDIT:
My intention is that I can do:
Child foo;
auto bar = make_parent(foo);
(As opposed to the easier version in the other answer, where I pass a pointer.)
Upvotes: 0
Views: 72
Reputation: 180945
All of this can be simplified to
template<typename T>
Parent<T>* get_parent_ptr(Parent<T>& param) { return ¶m; }
This will give you the pointer to the Parent
part of anything derived from Parent
If you want to be able to handle const
objects as well, and prevent getting a pointer to a temporary, unfortunately you will have to add a little more by adding
template<typename T>
const Parent<T>* get_parent_ptr(const Parent<T>& param) { return ¶m; }
template<typename T>
Parent<T>* get_parent_ptr(Parent<T>&& param) = delete; // if you don't care about getting a pointer to a rvalue you can remove this
You can see all of this working with this live example:
int main()
{
Child c;
auto cp = get_parent_ptr(c);
const Child cc;
auto ccp = get_parent_ptr(cc);
//auto error = get_parent_ptr(Child{});
}
If you uncomment the error
line you will get and error that you are trying to use a deleted function.
Upvotes: 3