带有const类型参数或简单类型的方法的C ++模板函数

时间:2016-02-05 22:10:23

标签: c++ templates traits template-deduction

假设我有两个模板函数用于调用类方法的相同主体,如:

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

我试着写一次正文,那么当被调用的方法有一个参数const并且它有参数时,让编译器使用它的正确方法是什么? const

3 个答案:

答案 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;
}

希望有所帮助!

答案 1 :(得分: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;
}

答案 2 :(得分: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;
}

有什么想法吗?