我想存储成员函数指针的模板是这样的:(这是我真正的代码的简化版本)
template<class Arg1>
void connect(void (T::*f)(Arg1))
{
//Do some stuff
}
template<class Arg1>
void connect(void (T::*f)())
{
//Do some stuff
}
class GApp
{
public:
void foo() {}
void foo(double d) {}
};
然后,我想做像在每个国家新闻出版总署重载的方法如下:
connect(&GApp::foo);
调用此为foo()
是好的,但我怎么能叫这个为foo(double d)
为什么不是以下工作?
connect((&GApp::foo)(double));
它会给我
语法错误:“双”前应先“)”
我不明白,必须在此处使用的语法。 这可能是一个愚蠢的qustion,但任何一个可以帮我在这?
Answer 1:
您作为编写的代码不能编译。 我已经做了一些关于你想要做什么“假设”,并更改了代码。
总之,您可以通过显式指定函数参数类型调用正确的函数:
connect<double> (&GApp::foo);
如果连接方法是一类模板的成员,那么只需要指定一次类类型:
template <typename T> class A
{
public:
template<class Arg1>
void connect(void (T::*f)(Arg1))
{
//Do some stuff
}
void connect(void (T::*f)())
{
//Do some stuff
}
};
class GApp
{
public:
void foo() {}
void foo(double d) {}
};
int main ()
{
A<GApp> a;
a.connect (&GApp::foo); // foo ()
a.connect<double> (&GApp::foo); // foo (double)
}
更新:
响应于新的代码示例中,所有的信息被在过去了,“罕见”的情况下是“signal_void”的情况下,因为这是其中信号具有模板参数,但成员函数没有。 因此,我们特别情况下例如,然后我们就大功告成了。 下面现在编译:
template <class Arg = void>
class signal {};
signal<double> signal_double;
signal<> signal_void;
// Arg1 is deduced from signal<Arg1> and then we use it in the declaration
// of the pointer to member function
template<class T, class Arg1>
void connect ( signal<Arg1>& sig, T& obj, void (T::*f)(Arg1) ) {}
// Add special case for 'void' without any arguments
template<class T>
void connect (signal<> & sig, T& obj, void (T::*f)()) {}
void bar ()
{
GApp myGApp;
//Connecting foo()
connect(signal_void, myGApp, &GApp::foo); // Matches second overload
//Connecting foo(double)
connect(signal_double, myGApp, &GApp::foo); // Matches first overload
}
Answer 2:
C ++编程语言,3E,第7.7节,P159:
您可以通过分配或初始化函数指针采取重载函数的地址。 在这种情况下,目标的类型用于从该组的重载函数选择。 例如:
void f(int);
int f(char);
void (*pf1)(int) = &f; // void f(int);
int (*pf2)(char) = &f; // int f(char);
void (*pf3)(char) = &f; // error: no void f(char)
据我知道(没有检查),同样适用于成员函数。 因此,解决方案可能是两行分裂:
connect((&GApp::foo)(double));
变为:
void (GApp::*tmp)(double) = &GApp::foo;
connect(tmp);
不要调用变量tmp
;-)
我猜想,newacct的演职人员是安全的也完全相同的原因。 投射到void (GApp::*)(double)
被定义为相同的初始化临时类型的void (GApp::*)(double)
。 由于用来初始化它表达的是&GApp::foo
,我希望同样的魔力应用到塑像作为适用于任何其他初始化与重载函数。 斯特劳斯不说“初始化指针到函数的变量”,他说,“初始化指针到函数”。 所以这应该包括临时工。
所以,如果你喜欢一个班轮:
connect((void (GApp::*)(double))(&GApp::foo));
然而,我假设的标准具有一致性,同样的想法,因为我做的,我没有检查。
Answer 3:
您可以尝试明确铸造的指针,让它知道该选择哪一个,就像这样:
connect((void (GApp::*)(double))&GApp::foo);
免责声明:没有测试
Answer 4:
这是工作,
typedef void (GApp::*MemberFunctionType)(double);
MemberFunctionType pointer = &GApp::foo;
connect(MemberFunctionType);
这是为什么 ?
编辑
嗯..是啊。 它是同newacct的解决方案。 谁能给一个解决方案请?
Answer 5:
使用boost ::函数库...
#include <boost/function.hpp>
template<class Arg1>
void connect(boost::function1<void, Arg1*> fn)
{
//Do some stuff
}
template<class Arg1>
void connect(boost::function2<void, Arg1*, double> fn)
{
//Do some stuff
}
class GApp
{
public:
void foo() {}
void foo(double d) {}
};
int main()
{
boost::function1<void,GApp*> f1 = (void (GApp::*)(void)) &GApp::foo;
boost::function2<void,GApp*,double> f2 = (void (GApp::*)(double)) &GApp:foo;
connect(f1);
connect(f2);
return 0;
}
Answer 6:
我原来的代码是这样的,
连接器....
template<class T, class Arg1>
void connect(signal<Arg1>& sig,T& obj, void (T::*f)())
{
// sig.insert(new GFunction<T, Arg1>(&obj,f));
}
template<class T, class Arg1
void connect(signal<Arg1>& sig,T& obj, void (T::*f)(Arg1))
{
// sig.insert(new GFunction<T, Arg1>(&obj,f));
}
信号...
signal<double> signal_double;
signal<> signal_void;
应用...
class GApp
{
public:
void foo() {}
void foo(double d) {}
};
Finaly,连接...
//Connecting foo()
connect(signal_void, myGApp, &GApp::foo()); //Ok
//Connecting foo(double)
connect(signal_double, myGApp, &GApp::foo()); // but ERROR!
没有为信号(未在这里提到的)模板类里面。 现在我希望这是更清晰的情况。 (或者是相同previouse?)。 如果没有那foo的第二个连接就可以了()(仅FOO(双))。 这是我的代码伤害我的事。 :(
文章来源: Overloaded member function pointer to template