为什么你的代码不起作用
模板参数port
和pin
只是形式参数。例如,对于常规功能,您是否期望
void foo(int x) { /* bla */ }
和
void foo(int y) { /* meh */ }
彼此不同?实际上,您可以仅通过签名在标头中简单地声明此类函数void foo(int)
。要重载函数,您需要提供不同的参数。
使用模板参数,它的工作原理完全相同
template<typename port> class invert { /* bla */ };
和
template<typename pin> class invert { /* bla */ };
具有相同的模板签名,实际上可以template<typename> class invert;
在标头内声明。
在这里,类比不成立,因为类模板不会重载,但必须专门化。这意味着invert
无论您在类实现本身中编写什么内容,您的两个版本的参数结构都需要“足够不同”。
如何修复它
为了得到你想要的,你实际上至少需要专门化其中一个模板。执行此操作的典型方法已在此处解释过,并且是定义一个特征类并在编译时使用 SFINAE 进行选择:
template <typename T>
class has_n_pins
{
typedef char one;
typedef long two;
template <typename C> static one test( typeof(&C::n_pins) ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
template<typename T, bool = has_n_pins<T>::value >
class invert: public T
{
// your current port implementation
};
// specialization for types T that don't have a n_pins() member function
template<typename T>
class invert<T, false>: public T
{
// your current pin implementation
};
现在有两个专业化:(invert<T, true>
所有T
有n_pins()
)和invert<T, false>
(所有T
没有)。编译器现在可以根据您实际提供的模板参数选择合适的参数。