在嵌入式编程中,处理中断,我需要编译器在编译时知道作为全局变量的类指针的地址,以及IO寄存器的一些地址。为了做到这一点,我正在尝试使模板函数处理ISR并具有指向它的指针模板参数:
template<MyClass &C, unsigned char PORT1, unsigned char PORT2>
void MyISR()
{
...
}
在初始化函数中,我想设置中断:
template<unsigned char PORT1, unsigned char PORT2>
class MyClass: public MyClassFunctionality
{
...
void init()
{
SetISR(MyISR<this,PORT1,PORT2>);
}
}
我知道指针this
不是常量,但我也知道每个模板参数集只会有一个全局实例。
一种解决方案是将函数指针传递给MyClass::init
并在函数调用中定义模板参数:
MyClass myclassinstance<100,101>;
...
myclassinstance.init(MyISR<myclassinstance,100,101>);
我不喜欢这个,因为它依赖于类的用户正确设置指针和端口号。
您可以看到哪些架构解决方法不涉及在MyISR<...>
调用中再次为init
键入模板pàrameters。
答案 0 :(得分:0)
专业化怎么样?
template <typename T, T* p> struct IsrHelper;
template <unsigned char PORT1,
unsigned char PORT2,
MyClass<PORT1, PORT2>* p>
struct IsrHelper<MyClass<PORT1, PORT2>, p>
{
void operator()() const
{
// ...
}
};
template<typename T, T* p>
void MyISR()
{
IsrHelper<T, p>{}();
}
然后
MyClass<100, 101> myclassinstance;
int main()
{
SetISR(&MyISR<decltype(myclassinstance), &myclassinstance)>);
}
在C ++ 17中,您可以使用auto
删除第一个参数并直接使用:
template <auto* p> struct IsrHelper;
template <unsigned char PORT1, unsigned char PORT2, MyClass<PORT1, PORT2>* p>
struct IsrHelper<p> { /**/ };
template<auto* p> void MyISR() { IsrHelper<p>{}(); }
// ...
SetISR(MyISR<&myclassinstance>);