替代无效的作为参数传递给模板方法
在我的代码我有注册其他类别的方法的一类:替代无效的作为参数传递给模板方法
#include <iostream>
using namespace std;
template< typename C>
class Reg {
public:
template< typename R, typename A>
void register_f(string name, R (C:: *method_p) (A)) { /*registration process*/ }
// template< typename R>
// void register_void_f(string name, R (C:: *method_p) (void)) { /*registration process*/ }
};
class A {
public:
int f(void) { return 1; }
void g(int x) { /* some code*/ }
};
int main() {
Reg< A> r;
r.register_f("g", &A::g);
/*1*/// r.register_f("f", &A::f);
/*2*/// r.register_f< int, void>("f", &A::f);
/*3*/// r.register_void_f< int>("f", &A::f);
return 0;
}
取消注释行/ * 2 * /给我一个错误:
template argument deduction/substitution failed:
In substitution of ‘template void register_f(std::string, R (C::*)(A)) [with R = R; A = A; C = A] [with R = int; A = void]’:
error: invalid parameter type ‘void’
线/ * 1 /相同/ 2 * /,但并非如此信息的错误消息。
我明白,要解决我可以使用方法register_void_f的问题,但我不想这样做,因为register_f是我最后的API的一部分。
问题>如何解决编译错误而不引入register_void_f?
我有一个想法解决它与部分专业register_f,但我不知道该怎么做,因为在C++中,你不能部分专门化模板方法。
PS>我不能使用C++ 11。
超载的功能:
void foo(int) {}
double bar() { return 3.14; }
template< class R, class A >
void test( R (*method_p) (A)) { }
template< class R >
void test( R (*method_p)()) { }
int main(){
test(foo);
test(bar);
}
转换这是它方法应该很容易。
不要使用void
对于没有参数,使用什么 - 这样的事情:
template< typename R>
void register_void_f(string name, R (C:: *method_p)()) { /*registration process*/ }
的问题是如何做到这一点不** ** register_void_f。我认为使用或不**无效**没有区别。 – 2014-09-22 14:14:51
如何使用不带参数的版本重载'register_f'? – Alex 2014-09-22 14:17:53
使用继承,你的意思是? – 2014-09-22 14:23:28
您可以使用以下方法:
template< typename C> class Reg;
template <typename C, typename F> struct helper;
template <typename C, typename R, typename A>
struct helper<C, R (C::*)(A)>
{
void operator() (Reg<C>& reg, const std::string& name, R (C::*method)(A)) const { /* Your implementation */}
};
template <typename C, typename R>
struct helper<C, R (C::*)()>
{
void operator() (Reg<C>& reg, const std::string& name, R (C::*method)()) const { /* Your implementation */}
};
template< typename C>
class Reg {
public:
template< typename F>
void register_f(const std::string& name, F method) { helper<C, F>()(*this, name, method); /*registration process*/ }
};
而使用它的方式:
Reg< A> r;
r.register_f("g", &A::g);
r.register_f("f", &A::f);
r.register_f<int (A::*)(void)>("f", &A::f);
谢谢雅克,奇怪的是它有效! http://ideone.com/Jk3NOp – 2014-09-22 14:26:51
我认为这将很难专业化。 – 2014-09-22 14:27:38
@ValentinT。重写不是专业化。专业化是不同的,并且*通常*与功能不好的想法(你最好重写)。如果你需要花哨的专业化,你通常会转向一门专业机械课程,而不是专业化的功能模板。 – Yakk 2014-09-22 14:32:34