尝试在 Arduino 中使用模板而不是重载函数:未在此范围中声明类型 [英] Attempting to use a Template instead of an Overloaded Function in Arduino: TYPE not declared in this Scope

查看:85
本文介绍了尝试在 Arduino 中使用模板而不是重载函数:未在此范围中声明类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个可以将数据移出到 74HC595 移位寄存器的函数,该寄存器可以移出 8、16 和 32 位值.

I'm trying to write a function that can Shift out data to 74HC595 shift registers which can shift out 8, 16, and 32 bit values.

使用重载函数,我有这个:

Using an overloaded function, I have this:

/**********************************************************************************
* Software SPI Pin Settings
*********************************************************************************/
#define SPIPINPORT  PORTB   //The Port that the Pins are on.  
#define LatchPin    2   //_RCLK  Shift register clock pin       
#define DataPin     3   //SER DS Serial data input              
#define ClockPin    5

/**********************************************************************************
* Preproccesor PIN to PIN Mask
*********************************************************************************/
#define LATCHMASK   (1 << LatchPin) 
#define MOSIMASK    (1 << DataPin)              
#define CLOCKMASK   (1 << ClockPin) 

/**********************************************************************************
* Macros
*********************************************************************************/
#define tggl(port,bit) (port)^=(1<<(bit))
#define LATCH   (SPIPINPORT &=~ LATCHMASK) 
#define unLATCH (SPIPINPORT |= LATCHMASK)  
#define PULSE   { tggl(SPIPINPORT,ClockPin); tggl(SPIPINPORT,ClockPin); }


void zShiftClass::ShiftOut(uint8_t value)
{
    LATCH;
    for (uint8_t i = 0; i <= 7; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}

void zShiftClass::ShiftOut(uint16_t value)
{
    LATCH;
    for (uint8_t i = 0; i <= 15; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}


void zShiftClass::ShiftOut(uint32_t value)
{
    LATCH;
    for (uint8_t i = 0; i <= 31; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}

而且我想用这个模板来代替这些功能:

And I want to use this template to replace these functions:

template<typename TYPE>void Shift(TYPE value)
{
    uint8_t loops = (( 8 * sizeof(value) ) - 1 );

    LATCH;
    for (uint8_t i = 0; i <= loops; i++) 
    {   
        if( !!(value&(1<<i)) == true)   //If value is not a 1, turn off MOSIMASK
        { SPIPINPORT |= MOSIMASK; } 
        else    
        { SPIPINPORT &= ~MOSIMASK; }        

        PULSE;  //Pulse the Clock
    }
    unLATCH;
}

编译时出现以下错误:

 Compiling 'zLEDArray' for 'Arduino Uno' 
 zLEDArray.ino : variable or field 'Shift' declared void 
 zLEDArray.ino : 'TYPE' was not declared in this scope
 Error compiling

我做错了什么?

推荐答案

好吧,这属于提防带有礼物的开发工具"的范畴.Arduino 草图工具是您的问题.如果您在首选项菜单上打开详细编译器输出,您将深入了解会发生什么.使用您的代码,我可以复制您的错误.编译一个名为template1的测试项目时,报同样的错误,但是现在可以看到编译器命令行了:

Okay, this falls in the category of "beware of dev tools bearing gifts". The Arduino sketch tool is your problem. If you turn on verbose compiler output on the preferences menu, you will get some insight into what happens. With your code, I can duplicate your error. When compiling a test project called template1, the same error is reported, but now can see the compiler command line:

D:\arduino-dev\arduino-1.0.3\hardware\tools\avr\bin\avr-g++ -c ...yada yada
more yada... e:\Temp\build3528223623599856131.tmp\template1.cpp ...
template1:14: error: variable or field 'Shift' declared void
template1:14: error: 'TYPE' was not declared in this scope

关键是那个.CPP文件.这是开发环境从您的 .INO 构建的文件,并且是编译器的实际输入.如果你去抓取那个文件,你会看到你的所有代码,包括一些额外的行:

The key point is that .CPP file. That is a file that the dev environment constructs from your .INO and is what is the actual input to the compiler. If you go grab that file, you will see all your code with some bonus lines included:

#include "Arduino.h"
void Shift(TYPE value);
void setup();
void loop();

为你添加的构建工具,4行:

The build tool added for you, 4 lines:

  • Arduino 标头(因为没人记得这个)
  • 通过解析代码得出的函数的 3 个前向声明

尝试从函数模板生成前向声明是不正确的,并生成导致编译器错误的代码.

The attempt at producing a forward declaration from the function template is incorrect, and produces the code that results in the compiler error.

解决方案是将模板从 .INO 文件中移出.

The solution is to move the template out from the .INO file.

  1. 创建一个库文件夹,比如 T1.
  2. 在该文件夹中使用模板代码创建一个 .H 文件,例如 tspi.h.
  3. 将库导入您的项目.
  4. 确保#include 行在您的 .INO 中的第一行代码之后(更奇怪的是 - 该工具将在所有注释之后但在第一行代码之前插入一个 #include Arduino.h".如果您离开您包含在 .INO 文件的顶部,它将在 Arduino 标头之前处理)

这篇关于尝试在 Arduino 中使用模板而不是重载函数:未在此范围中声明类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆