C++ 重载C++;不复制代码的模板函数

C++ 重载C++;不复制代码的模板函数,c++,C++,我编写了以下函数: template< class C, typename T, typename U > void addVarCB(C * _this, const std::string &name, T(C::*getter)(void) const, U(C::*setter)(const T&), const std::string &def); template< class C, typename T, typename U

我编写了以下函数:

template< class C, typename T, typename U >
void addVarCB(C * _this, const std::string &name, 
    T(C::*getter)(void) const, U(C::*setter)(const T&), const std::string &def);
template< class C, typename T, typename U >
void addVarCB(C * _this, const std::string &name, 
T(C::*getter)(void) const, U(C::*setter)(T), const std::string &def = "");
我注定要到处复制相同的代码吗? 希望至少能为参考版本提供解决方案

请注意,该函数使用指向对象、getter和setter公共成员函数的this指针。
然后,该函数将与GUI接口,允许稍后调用getter和setter。

只需将
GetType
SetType
作为独立的模板参数,并让编译器担心它们是否可转换

例如:

template< class C, typename T, typename U >
void addVarCB(C * _this, const std::string &name, 
    T(C::*getter)(void) const, U(C::*setter)(const T&), const std::string &def);
允许
setter
参数和
getter
返回类型不同。现在,假设您想要将一个传递给另一个,那么只有当它们是可转换的(或者您可以使用C++11或Boost.TypeTraits
is_convertable
来明确断言这一点)时,它才会编译



。。。如果这不起作用,那么如果您展示一下addVarCB的内部内容,或者解释一下您想要实现什么,可能会有所帮助。

一些模板元编程可以解决您的问题:(下面需要C++11,但使用boost也可以实现同样的功能)

#包括
#包括
模板
结构基类型{
typedef typename std::remove_const::type type;
};
结构MyClass{
INTA;
std::字符串s;
const int&getA()const{return a;}
void setA(inta){this->a=a;}
std::string get()常量{return s;}
};
模板<类别C,类型名Tget,类型名Tset,类型名U,
class=typename std::启用<
std::是一样的吗<
typename BaseType::type,
typename BaseType::type>::value,void>::type>
void addVarCB(C*_this,const std::string&name,
Tget(C::*getter)(void)const,U(C::*setter)(Tset),const std::string&def=“”){
}
int main(){
MyClass c;
addVarCB(&c,std::string(“a”),&MyClass::getA,&MyClass::setA,std::string(“a”);
//addVarCB(&c,std::string(“a”),&MyClass::get,&MyClass::setA,std::string(“a”);//编译器错误
}

这里,我们简单地让get和set类型(分别是
Tget
Tset
)独立推导。然后我们去掉这些类型的常量或引用,检查它们是否相同;如果没有,我们将使用
enable\u触发专门化失败如果

请解释一下这里的意思,我没有GetType或SetType。此外,“T”不能被推断为“const T&”,因此将T(C::*getter)(void)更改为S(C::*getter)(void)没有任何作用……@aCuria:
T
可以很好地推断为
T(C:*getter)(
)中的任何参数,包括
某种类型的const&
template< class C, typename T, typename U >
void addVarCB(C * _this, const std::string &name, 
    T(C::*getter)(void) const, U(C::*setter)(const T&), const std::string &def);
template <typename Class, typename GetResult, typename SetArg, typename SetResult>
void addVarCB(Class *instance, std::string const& name,
              GetResult (Class::*getter)() const,
              SetResult (Class::*setter)(SetArg),
              std::string const &def);
#include<string>
#include<type_traits>

template<typename T>
struct BaseType {
    typedef typename std::remove_const<typename std::remove_reference<T>::type>::type type;
};

struct MyClass{
    int a;
    std::string s;
    const int & getA() const {return a;}
    void setA(int a) {this->a=a;}
    std::string getS() const {return s;}
};


template< class C, typename Tget, typename Tset, typename U, 
    class = typename std::enable_if<
                std::is_same<
                   typename BaseType<Tget>::type, 
                   typename BaseType<Tset>::type>::value,void>::type >
void addVarCB(C * _this, const std::string &name, 
    Tget(C::*getter)(void) const, U(C::*setter)(Tset), const std::string &def = "") {
}

int main() {
    MyClass c;
    addVarCB(&c,std::string("a"),&MyClass::getA,&MyClass::setA,std::string("a"));
    //addVarCB(&c,std::string("a"),&MyClass::getS,&MyClass::setA,std::string("a")); // Compiler error
}