获取当前创建的实例作为模板参数

时间:2017-09-08 08:12:35

标签: c++ templates

在嵌入式编程中,处理中断,我需要编译器在编译时知道作为全局变量的类指针的地址,以及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。

1 个答案:

答案 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>);