访问嵌套 class 模板的静态成员函数

Accessing a static member function of a nested class template

出于学术目的,我正在重新发明轮子并尝试编写一个 HAL 库。现在在设计的时候遇到了一个我不明白的编译错误

template< class DRIVER, class PORT, class PIN >
class Instance
{
        Instance(){}
    public: 

        static void set(const bool val) 
      { 
        DRIVER::GPIOPeripheral<PORT, PIN>::set(val); 
      }
      // ...
};

想法是,驱动程序 class 定义 'how',而 GPIO class 定义 GPIO 接口抽象。

驱动程序 class 看起来像这样:

class SOC_xyz 
{
    SOC_xyz(){};

public:
    template<class PORT, class PIN>
    class GPIOPeripheral
    {
        static void set(const bool val){ /* ... */ };
    }
};

实际代码中的调用如下所示:

typedef Instance<SOC_t, PORT0_t, PIN0_t> GPIO0_0;
GPIO0_0::set(1);

现在编译器给了我一个

error: expected primary-expression before ',' token

用于调用 DRIVER::GPIOPeripheral<PORT, PIN>Instance::set 函数。根据我的理解,它试图告诉我 class-template-member 寻址部分是错误的,但这超出了我的 C++ 知识范围。那是我尝试做的,甚至可能吗?

DRIVER::GPIOPeripheral<PORT, PIN>::set(val);

DRIVERInstance class 模板的类型模板参数,但是主 class 模板不知道任何依赖类型 GPIOPeripheral 参数化类型DRIVER;它只知道后者是一个类型(DRIVER甚至可能不是class类型)。

当您设计主要 class 模板时,允许调用参数化类型 DRIVER 的从属 class 模板 的成员函数],你需要告诉编译器:

DRIVER::template GPIOPeripheral<PORT, PIN>::set(val);
//      ^^^^^^^^

正式声明Instanceclass模板的DRIVER类型模板参数的dependent nameGPIOPeripheral为模板

The template disambiguator for dependent names

Similarly, in a template definition, a dependent name that is not a member of the current instantiation is not considered to be a template name unless the disambiguation keyword template is used or unless it was already established as a template name: [...]


此外,请注意,当您使用 class 声明 GPIOPeripheral class 模板时,默认访问修饰符 private,即 set成员函数是私有的,不能从朋友的 class 模板本身的(词法)范围之外访问。