Assuming I have the same body for two template functions for calling class methods, like these:
template <typename jsType, typename jsParamType, typename ParamPrivateType = jsParamType::PrivateType, void(PrivateType::*Method)(const ParamPrivateType&)>
static bool SetByRefMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
}
template <typename jsType, typename jsParamType, typename ParamPrivateType = jsParamType::PrivateType, void(PrivateType::*Method)( ParamPrivateType&)>
static bool SetByRefMethod(JSContext *cx, unsigned argc, JS::Value *vp)
{
...
}
I try to write once the body, so what is the right way to make the compiler to use it when the called method has a parameter const
and when it has a parameter not const
?
Here is a solution, but, is there a better way?
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
#include <type_traits>
class A {
public:
using ClassType = int;
void print_const_integer(const int& a) {
cout << "A's member function accepting a const ref called" << endl;
cout << a << endl;
}
void print_integer(int& a) {
cout << "A's member function accepting a ref called" << endl;
cout << a << endl;
}
};
class B {
public:
using ClassType = int;
void print_integer(int& a) {
cout << "B's member function called" << endl;
cout << a << endl;
}
};
template <typename TYPE, void(TYPE::*member_func_pointer)(int&)>
void function(TYPE object) {
typename TYPE::ClassType a = 1;
(object.*member_func_pointer)(a);
}
template <typename TYPE, void(TYPE::*member_func_pointer)(const int&)>
void function(TYPE object) {
typename TYPE::ClassType a = 1;
(object.*member_func_pointer)(a);
}
template <typename TYPE, typename FUNCTYPE>
struct opt_const_param : std::enable_if<std::is_same<FUNCTYPE, void(TYPE::*)( int&)>::value
|| std::is_same<FUNCTYPE, void(TYPE::*)(const int&)>::value, FUNCTYPE>
{
};
template <typename TYPE, typename FUNCTYPE, typename opt_const_param<TYPE, FUNCTYPE>::type member_func_pointer>
void function2(TYPE object) {
typename TYPE::ClassType a = 1;
(object.*member_func_pointer)(a);
}
int main() {
A a;
B b;
function2<A, void(A::*)(const int&), &A::print_const_integer>(a);
function2<A, void(A::*)(int&), &A::print_integer>(a);
function2<B, void(B::*)(int&), &B::print_integer>(b);
return 0;
}