[英]Substitution of void as parameter to templated method
In my code I have a class which registers method's of other classes: 在我的代码中,我有一个类,它注册其他类的方法:
#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;
}
http://ideone.com/X8PNLC http://ideone.com/X8PNLC
Uncommenting line /* 2 */ gives me an error: 取消注释行/ * 2 * /给我一个错误:
template argument deduction/substitution failed:
模板参数扣除/替换失败:
In substitution of 'template void register_f(std::string, R (C::*)(A)) [with R = R;
代替'template void register_f(std :: string,R(C :: *)(A))[用R = R; A = A;
A = A; C = A] [with R = int;
C = A] [R = int; A = void]':
A = void]':
error: invalid parameter type 'void'
错误:参数类型无效'void'
Line /* 1 / is the same as / 2 */, but with not so informative error message. 行/ * 1 /与/ 2 * / 相同 ,但没有提供如此丰富的错误消息。
I understand that to fix the problem I can use method register_void_f , but I don't want to do it because register_f is a part of the my final API. 我理解为了解决问题,我可以使用方法register_void_f ,但我不想这样做,因为register_f是我最终API的一部分。
Question> How to fix the compilation errors without introducing register_void_f ? 问题>如何在不引入register_void_f的情况下修复编译错误?
I have an idea to solve it with partial specialized register_f , but I don't know how to do it since in C++ you can't partially specialize templated method. 我有一个想法,用部分专门的register_f来解决它,但我不知道怎么做,因为在C ++中你不能部分地专门化模板化方法。
PS> I can't use C++11. PS>我不能使用C ++ 11。
Don't use void
for no arguments, use nothing - something like this: 不要使用
void
作为参数,不使用任何东西 - 像这样:
template< typename R>
void register_void_f( string name, R ( C:: *method_p ) ()) { /*registration process*/ }
Overload your function: 超载你的功能:
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);
}
Converting this to it being methods should be easy. 将其转换为方法应该很容易。
You may use the following: 您可以使用以下内容:
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*/ }
};
And use it that way: 并以这种方式使用它:
Reg< A> r;
r.register_f( "g", &A::g);
r.register_f( "f", &A::f);
r.register_f<int (A::*)(void)>( "f", &A::f);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.