Перегрузить операторы в функцию без записи тела 2 раза - PullRequest
2 голосов
/ 10 марта 2020

В настоящее время у меня есть этот код:

void writeLog(__FlashStringHelper* mes){

  Serial.println(mes);

  if(!logfile){
    logfile = SD.open(logpath,FILE_WRITE);
    if(!logfile) return;
  }

  logfile.write(mes);

}

void writeLog(char* mes){

  Serial.println(mes);

  if(!logfile){
    logfile = SD.open(logpath,FILE_WRITE);
    if(!logfile) return;
  }

  logfile.write(mes);

}

Есть ли способ перегрузить функцию для принятия char * и __FlashStringHelper * без записи тела 2 раза?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 10 марта 2020

Если вы можете использовать шаблоны, попробуйте это:

template <typename T>
void writeLog(T mes) {

    Serial.println(mes);

    if (!logfile) {
        logfile = SD.open(logpath, FILE_WRITE);
        if (!logfile) return;
    }

    logfile.write(mes);

}
2 голосов
/ 10 марта 2020

Это в значительной степени точно для чего функции шаблона предназначены для! Вам нужно написать только одну шаблонную функцию в вашем случае, как показано ниже:

template<typename T>
void writeLog(T mes)
{
    Serial.println(mes);
    if (!logfile) {
        logfile = SD.open(logpath, FILE_WRITE);
        if (!logfile) return;
    }
    logfile.write(mes);
}

Затем вы можете вызвать это с аргументом любого допустимого типа. Если вы попытаетесь вызвать его с типом аргумента, для которого нет совместимой версии вызовов Serial.println или logfile.write, то компилятор выдаст ошибку. В противном случае компилятор сгенерирует код для соответствующей real функции, как и когда вы сделаете правильный вызов. Таким образом, ваш main может выглядеть примерно так:

int main()
{
    char text[256];
    writeLog(text); // OK: Compiler will generate the code equivalent to your second function
    __FlashStringHelper fsh;
    writeLog(&fsh); // OK: Compiler will generate the code equivalent to your first function
    int p;
//    writeLog(p);  //Error: No suitable versions of "Serial.println()" and "logfile.write()" with an int parameter
    return 1;
}

РЕДАКТИРОВАТЬ: Если вы знаете, что все вызовы вашей функции будут выполняться с использованием типа pointer в качестве аргумента, вы может сделать ваш шаблон более конкретным c (и, следовательно, лучше обнаруживать неправильное использование), указав аргумент в качестве указателя:

template<typename T>
void writeLog(T* mes)
{
//...
0 голосов
/ 11 марта 2020

Спасибо всем, я нашел решение! Существует класс, который поставляется с Arduino IDE, который называется String. Он поддерживает неявное приведение типов из __FlashStringHelper * и char *.

void writeLog(String mes){

  Serial.println(mes);

  if(!logfile){
    logfile = SD.open(logpath,FILE_WRITE);
    if(!logfile) return;
  }

  logfile.println(mes);

}

writeLog("A string from RAM");
writeLog(F("A string from flash memory"));
...