2016-02-05 5 views
2

Предполагая, что у меня есть такое же тело для двух шаблонных функций для вызова методов класса, как эти:C++ шаблон функция для метода с параметром константного типа или просто типа

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) 
{ 
... 
} 

Я стараюсь писать, как только body, так что это правильный способ заставить компилятор использовать его, когда вызываемый метод имеет параметр const и когда он имеет параметр неconst?

+0

Вы можете взять указатель на функцию в качестве шаблона 'typename Func'. В стороне, ваши шаблоны выглядят странно. – AndyG

+0

Это всего лишь случай, у меня есть другие типы функций для вызова. Я связан с некоторыми сторонними API-интерфейсами, которые я не могу коснуться, поэтому мне нужно использовать шаблоны для параметризации. – mike

+0

Это даже не похоже, что он скомпилируется для меня. Параметры шаблона без дефолта не могут соответствовать параметру шаблона по умолчанию. –

ответ

0

Вот решение, но есть ли лучший способ?

#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; 
} 
0

Вам не нужно создавать шаблоны всех этих типов. Только первый будет делать. Если вы можете вывести остальные типы, используя первый шаблонный тип, вы должны быть в порядке. Вам не нужны частные типы в шаблоне, если они могут быть выведены из первого типа шаблона. Выполните следующий код

#include <iostream> 
using std::cout; 
using std::endl; 
#include <vector> 
using std::vector; 

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 function(TYPE object, void (TYPE::*member_func_pointer)(int&)) { 
    typename TYPE::ClassType a = 1; 
    (object.*member_func_pointer)(a); 
} 

template <typename TYPE> 
void function(TYPE object, void (TYPE::*member_func_pointer)(const int&)) { 
    typename TYPE::ClassType a = 1; 
    (object.*member_func_pointer)(a); 
} 

int main() { 
    A a; 
    B b; 

    function(a, &A::print_const_integer); 
    function(a, &A::print_integer); 
    function(b, &B::print_integer); 

    return 0; 
} 

Надейтесь, что помогли!

+0

Это то, что у меня уже есть. За исключением вместо '(object. * Member_func_pointer) (a);' У меня есть большое тело, как в вашем примере, дважды. Поэтому я надеюсь, что я смогу использовать некоторые 'std :: enable_if',' std :: is_same' и связанные с ними вещи, чтобы уменьшить две функции, названные в вашем примере 'function', до одного. – mike

0

У меня есть другой подход здесь, он выглядит лучше для использования с макросами:

#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, typename FUNCTYPE> 
struct opt_const_param_function3 : 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_function3<TYPE, FUNCTYPE>::type member_func_pointer> //FUNCTYPE member_func_pointer> 
void function3(TYPE object) { 
    typename TYPE::ClassType a = 1; 
    (object.*member_func_pointer)(a); 
} 

template <typename TYPE, void(TYPE::*member_func_pointer)(int&)> 
void function3(TYPE object) { 
    function3<TYPE, decltype(member_func_pointer), member_func_pointer>(object); 
} 

template <typename TYPE, void(TYPE::*member_func_pointer)(const int&)> 
void function3(TYPE object) { 
    function3<TYPE, decltype(member_func_pointer), member_func_pointer>(object); 
} 

int main() { 
    A a; 
    B b; 

    function3<A, &A::print_const_integer>(a); 
    function3<A, &A::print_integer>(a); 
    function3<B, &B::print_integer>(b); 

    return 0; 
} 

Есть мысли?