如何从C++模板中的方法类型推导出类类型?

aka*_*vel 2 c++ generics templates traits

在如下所示的模板中,我希望调用Run(&Base::foo)成功,而无需将Base类型命名两次(如编译Run<Base>(&Base::foo)调用中所做的那样).我可以吗?可能没有添加大量的Boost标头?

使用提供的代码,我得到一个错误:

prog.cpp:26: error: no matching function for call to ‘Run(bool (Base::*)())’
Run Code Online (Sandbox Code Playgroud)

(你可以在http://ideone.com/8NZkq上摆弄这个片段):

#include <iostream>

class Base {
public:
  bool foo() { return true; }
};

Base* x;

template<typename T>
struct Traits {
  typedef bool (T::*BoolMethodPtr)();
};

template<typename T>
void Run(typename Traits<T>::BoolMethodPtr check) {
  T* y = dynamic_cast<T*>(x);
  std::cout << (y->*check)();
}

int main() {
  Base y;
  x = &y;
  Run<Base>(&Base::foo);
  Run(&Base::foo); // why error?
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*nau 10

TTraits<T>::BoolMethodPtr处于非推测范围内,所以编译器将不会从叫什么类型T应该是自动推断.这是因为可能有这样的代码:

template<typename T>
struct Traits {
  typedef bool (T::*BoolMethodPtr)();
};

template<>
struct Traits<int> {
  typedef bool (Base::*BoolMethodPtr)();
};

Run(&Base::foo); /* What should T be deduced to? Base and int are both equally possible */
Run Code Online (Sandbox Code Playgroud)

如果你没有Traits<T>上课,你可以写成Run:

template<class Class>
void Run(bool (Class::*check)()) {
  Class* y = dynamic_cast<Class*>(x);
  std::cout << (y->*check)();
}
Run Code Online (Sandbox Code Playgroud)

在这种背景下,Class可以推断出意思Base


Pot*_*ter 5

要区分一种类型(任何类型),请使用部分特化。没有函数模板部分专业化,因此您需要直接在其参数类型上参数化函数并检索内部的类类型。

template< typename T >
struct get_host_class; // most types are not ptmfs: don't implement this

template< typename C >
struct get_host_class< bool (C::*)() > { // implement partial specialization
     typedef C host;
     typedef void sfinae; // disallow function for non ptmf arguments
};

template< typename T >
typename get_host_class<T>::sfinae Run( T check) {
    typedef T BoolMethodPtr; // or something
    typedef typename get_host_class< T >::host host;
}
Run Code Online (Sandbox Code Playgroud)