Reputation: 4751
So I have a class:
struct C {
int x[10];
int const& get(int i) const { return x[i]; }
template<typename... Ts>
auto& get(Ts... args) {
int const& (C::*f)(Ts...) const = &C::get;
return const_cast<int&>((this->*f)(args...));
}
};
and the template will generate a non-const
getter on demand, so this becomes legal:
int& test(C& c) {
int i = 4;
int& r = c.get(i);
return r;
}
but if I change the original getter's argument type to a reference:
int const& get(int const& i) const { return x[i]; }
the non-const
getter template can't match the const
getter anymore.
Obviously it's no big deal passing an int
by value, and it's no big deal passing the argument list explicitly to the template, but I have more complex arguments and numerous overloads, and I'd like to infer all my non-const
getters with a minimum of copy-paste.
Is there any way past this?
One thought I had was that I could declare the problem argument list within the class but leave the definition to the template, so that the argument matching would have some guidance. I tried adding the following to the class (either before or after the template):
int& get(int const& i);
Unfortunately this bypasses the template altogether and results in a link error. Adding inline
or template
to the declaration didn't seem to do the trick either.
Upvotes: 1
Views: 226
Reputation: 32484
Why do you enforce the call to a const
member function through an auxiliary pointer to member-function? In such cases I use const
qualification of this
:
template<typename... Ts>
auto& get(Ts... args) {
const C* const const_this = this;
return const_cast<int&>(const_this->get(args...));
}
Upvotes: 2