我在我的 .h 文件中声明了以下模板类
enum class Hal_uart_id
{
Uart = 0,
Usart0,
Usart1,
Usart2,
Usart3,
UsbUart,
};
template <class T>
class HalUART
{
public:
HalUART(Hal_uart_id uart_id);
private:
Hal_uart_id _uart_id;
T* _p_uart;
}
在我的 .cpp 文件中,我按如下方式实现类构造函数:
#include "hal_uart_common.h"
#include "Arduino.h"
template <class T>
HalUART<T>::HalUART(Hal_uart_id id)
{
_uart_id = id;
switch (_uart_id)
{
case Hal_uart_id::Uart:
_p_uart = &Serial;
break;
case Hal_uart_id::UsbUart:
_p_uart = &SerialUSB;
break;
case Hal_uart_id::Usart0:
_p_uart = &Serial1;
break;
case Hal_uart_id::Usart1:
_p_uart = &Serial2;
break;
case Hal_uart_id::Usart3:
_p_uart = &Serial3;
break;
default:
break;
}
}
在我的 .cpp 文件的末尾,我用 USARTClass 类实例化了模板类
template class HalUART<USARTClass>;
我收到以下编译错误,我不明白为什么或如何修复它:
src/hal/uart/hal_uart_sam3x.cpp: In instantiation of 'HalUART<T>::HalUART(Hal_uart_id) [with T = USARTClass]':
src/hal/uart/hal_uart_sam3x.cpp:58:16: required from here
src/hal/uart/hal_uart_sam3x.cpp:23:21: error: invalid conversion from 'UARTClass*' to 'USARTClass*' [-fpermissive]
_p_uart = &Serial;
~~~~~~~~^~~~~~~~~
src/hal/uart/hal_uart_sam3x.cpp:26:21: error: cannot convert 'Serial_*' to 'USARTClass*' in assignment
_p_uart = &SerialUSB;
~~~~~~~~^~~~~~~~~~~~
*** [.pio/build/due/src/hal/uart/hal_uart_sam3x.cpp.o] Error 1
这些对象在Arduino核心中定义
UARTClass Serial;
USARTClass Serial1;
USARTClass Serial2;
USARTClass Serial3;
Serial_ SerialUSB;
有关 UART/USART 类和对象的定义,请参阅: https://github.com/arduino/ArduinoCore-sam/blob/master/cores/arduino/UARTClass.h https://github.com/arduino/ArduinoCore-sam/blob/master/cores/arduino/UARTClass.cpp
https://github.com/arduino/ArduinoCore-sam/blob/master/cores/arduino/USARTClass.h https://github.com/arduino/ArduinoCore-sam/blob/master/cores/arduino/USARTClass.cpp
https://github.com/arduino/ArduinoCore-sam/blob/master/cores/arduino/USB/USBAPI.h https://github.com/arduino/ArduinoCore-sam/blob/master/cores/arduino/USB/CDC.cpp
最佳答案
模板类型必须在编译时解决。用 template class HalUART<UARTClass>;
实例化你的类而不是 USARTClass
(一次 class USARTClass : public UARTClass;
)。而且,在 Serial_
中例如,使用 if constexpr
(仅限 C++17)与 std::is_same
:
case Hal_uart_id::UsbUart:
if constexpr (std::is_same_v<T, Serial_>)
_p_uart = &SerialUSB;
break;
我推荐使用 if constexpr
对于其他情况,一旦你用 Serial_
实例化了你的类,例如,那么您还可以 template class HalUART<USARTClass>;
:
switch (_uart_id)
{
case Hal_uart_id::Uart:
if constexpr (std::is_same_v<UARTClass, T>)
_p_uart = &Serial;
break;
case Hal_uart_id::UsbUart:
if constexpr (std::is_same_v<T, Serial_>)
_p_uart = &SerialUSB;
break;
case Hal_uart_id::Usart0:
if constexpr (std::is_same_v<USARTClass, T>)
_p_uart = &Serial1;
break;
case Hal_uart_id::Usart1:
if constexpr (std::is_same_v<USARTClass, T>)
_p_uart = &Serial2;
break;
case Hal_uart_id::Usart3:
if constexpr (std::is_same_v<USARTClass, T>)
_p_uart = &Serial3;
break;
default:
break;
}
通过这种类型检查,也许你的 switch
可能不再需要。尝试对此进行评估。
考虑使用 std::is_base_of
如有必要。
如果 c++17 不可用,请尝试专门化您的函数:
template <class T>
HalUART<T>::HalUART(Hal_uart_id id) {}
template <>
HalUART<UARTClass>::HalUART(Hal_uart_id id) {
if (id == Hal_uart_id::Uart)
_p_uart = &Serial;
}
template <>
HalUART<Serial_>::HalUART(Hal_uart_id id) {
if (id == Hal_uart_id::UsbUart)
_p_uart = &SerialUSB;
}
template <>
HalUART<USARTClass>::HalUART(Hal_uart_id id) {
if (id == Hal_uart_id::Usart0)
_p_uart = &Serial1;
else if (id == Hal_uart_id::Usart1)
_p_uart = &Serial2;
else if (id == Hal_uart_id::Usart3)
_p_uart = &Serial3;
}
关于c++ - 模板类实例化中的指针转换无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57958037/