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
该T在Traits<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
要区分一种类型(任何类型),请使用部分特化。没有函数模板部分专业化,因此您需要直接在其参数类型上参数化函数并检索内部的类类型。
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)