其他分享
首页 > 其他分享> > c – 指向成员函数的指针的模板类型推导

c – 指向成员函数的指针的模板类型推导

作者:互联网

我有一个与Morpheus提出的问题非常相似的问题,在下面的问题中:

Overloaded member function pointer to template

Richard Corden提出的解决方案要求用户明确指定函数参数类型,以区分它们的重载.但是,此解决方案似乎不适用于具有相同类型的不同数量的参数的重载.

考虑这个例子(源自原始问题):

template <typename T>
class A
{
public:
  template<class Arg1>
  void connect(void (T::*f)(Arg1)) 
  {
    //Do some stuff
  }

  template<class Arg1, class Arg2>
  void connect(void (T::*f)(Arg1,Arg2)) 
  {
    //Do some stuff
  }

  void connect(void (T::*f)()) 
  {
    //Do some stuff
  }
};

class GApp
{
public:
    void foo() {}
    void foo(double d) {}
    void foo(double d1, double d2) {}
};


int main ()
{
  A<GApp> a;
  a.connect (&GApp::foo);                // foo () - OK
  a.connect<double> (&GApp::foo);        // foo (double) - FAIL
  a.connect<double,double> (&GApp::foo); // foo (double,double) - OK
}

GNU G 3.4.5和MSVC 2008不编译上面的代码,两者都提供类似的错误消息:

test.cpp: In function `int main()':
test.cpp:36: error: call of overloaded `connect(<unknown type>)' is ambiguous
test.cpp:7: note: candidates are: void A<T>::connect(void (T::*)(Arg1)) [with Arg1 = double, T = GApp]
test3.cpp:13: note:               void A<T>::connect(void (T::*)(Arg1, Arg2)) [with Arg1 = double, Arg2 = double, T = GApp]

我知道一些可以使其编译的变通方法,比如将指针指定给完全相同类型的变量(例如void(GApp :: * tmp)(double)=& GApp :: foo;)或者,使用调用connect函数时更明确的形式(例如connect((void(GApp :: *)(double))(& GApp :: foo));).

但是,我更喜欢第一种解决方案,并想知道它为什么不起作用.

先感谢您!

解决方法:

对于a.connect< double> (& GApp :: foo),foo(double)和foo(double,double)都会匹配connect与one的重载,并分别与两个模板参数匹配(在两个参数版本的情况下,第二个模板)将推断出参数,第一个参数是由您明确提供的).

如果你想消除模棱两可的情况,我建议你传递确切的类型,这样就不会出现任何意外.而不是那些重载,为什么不有一个重载

template<typename MType, typename T>
void connect(MType T::*f) 
{
  //Do some stuff
}

a.connect<void()> (&GApp::foo);
a.connect<void(double)> (&GApp::foo);
a.connect<void(double, double)> (&GApp::foo);

最后一次调用connect也应该在你的代码中正常工作.然后,您可以在连接单独模板时剖析类型MType,以获取参数和返回类型.

标签:pointer-to-member,c,templates
来源: https://codeday.me/bug/20190726/1543533.html