访问嵌套 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);
DRIVER
是 Instance
class 模板的类型模板参数,但是主 class 模板不知道任何依赖类型 GPIOPeripheral
参数化类型DRIVER
;它只知道后者是一个类型(DRIVER
甚至可能不是class类型)。
当您设计主要 class 模板时,允许调用参数化类型 DRIVER
的从属 class 模板 的成员函数],你需要告诉编译器:
DRIVER::template GPIOPeripheral<PORT, PIN>::set(val);
// ^^^^^^^^
正式声明Instance
class模板的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 模板本身的(词法)范围之外访问。
出于学术目的,我正在重新发明轮子并尝试编写一个 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);
DRIVER
是 Instance
class 模板的类型模板参数,但是主 class 模板不知道任何依赖类型 GPIOPeripheral
参数化类型DRIVER
;它只知道后者是一个类型(DRIVER
甚至可能不是class类型)。
当您设计主要 class 模板时,允许调用参数化类型 DRIVER
的从属 class 模板 的成员函数],你需要告诉编译器:
DRIVER::template GPIOPeripheral<PORT, PIN>::set(val);
// ^^^^^^^^
正式声明Instance
class模板的DRIVER
类型模板参数的dependent nameGPIOPeripheral
为模板
The
template
disambiguator for dependent namesSimilarly, 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 模板本身的(词法)范围之外访问。