Использование шаблона внутри класса

Я пытаюсь использовать функцию шаблона, но получаю сообщение об ошибке

home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: sketch/emptyCode.ino.cpp.o: in function `startIOTservices()':
/home/guy/Documents/git/Arduino/HomePi/emptyCode/emptyCode.ino:37: undefined reference to `void myTest::funcOne<bool>(bool)'
/home/guy/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: sketch/emptyCode.ino.cpp.o: in function `setup':
/home/guy/Documents/git/Arduino/HomePi/emptyCode/emptyCode.ino:70: undefined reference to `void myTest::funcOne<bool>(bool)'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

внутри файла .cpp:

myTest::myTest()
{
        Serial.println("start");
}

template <class T1> 
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

внутри файла .h:

class myTest
{
public:
    myTest();
    template <class T1> 
    void funcOne(T1 arg);
};

и вызов его из файла .ino:

testA.funcOne(true);

Что я делаю не так?

ИЗМЕНИТЬ 1:

полные файлы .h .cpp, изначально принадлежащие библиотеке myJSON, которые удаляются в этом фрагменте

#ifndef myJSON_h
#define myJSON_h

#include "Arduino.h"
#include <ArduinoJson.h>
#include "FS.h"

#define DOC_SIZE 1000

class myJSON
{
};

class myTest
{
public:
    myTest();
    template <class T1> 
    void funcOne(T1 arg);
};

#endif

файл .cpp

#include "Arduino.h"
#include "myJSON.h"
#include "FS.h"
#include <ArduinoJson.h>

#define LOG_LENGTH 4

myJSON::myJSON(char *filename, bool useserial)
{
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~

myTest::myTest()
{
        Serial.println("start");
}

// шаблон <typename T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

, 👍0

Обсуждение

поместите определение функции шаблона в файл .h., @Juraj

@Juraj, когда я покидаю шаблон, определяющий только файл .h, я получаю: ошибка: переменная или поле 'funcOne' объявлено недействительным void myTest::funcOne(T1 arg), @Guy . D

Пожалуйста, предоставьте минимальный полный пример. Ошибка может быть в вызывающем/использующем источнике., @the busybee

@thebusybee Поскольку это всего лишь пример, я поместил класс myTest в другой файл .cpp и .h, которые я сейчас использую. funcOne вызывается во время функции setup(), @Guy . D

Не могли бы вы показать нам команды для компиляции и компоновки? О, и источник этого другого модуля, пожалуйста. Вы можете включить подробный вывод сборки в настройках., @the busybee

@thebusybee, что вы имеете в виду под командами для выполнения и ссылки?, @Guy . D

Возможно, вы захотите [отредактировать] свой вопрос с текущим кодом. Пожалуйста, не удаляйте старый код, потому что на него ссылаются комментарии., @the busybee

@thebusybee, редактировать нечего. просто воспроизвести проблему. он построен с помощью Arduino IDE., @Juraj

@thebusybee см. редактирование 1, @Guy . D

@Juraj, ты прав - Arduino IDE 1.8.2, @Guy . D

@Juraj ОП сказал: «_когда я покидаю шаблон, определяющий только файл .h, я получаю: ошибка ..._», поэтому источник не актуален. Поэтому я попросил актуальные источники. И я все еще скучаю по основному модулю, который вызывает funcOne(), так как упомянутая ошибка предположительно указывает на него., @the busybee


1 ответ


Лучший ответ:

2

переместите определение метода шаблона в .h или определите его в классе. это не реальная функция, а только предписание для функций. Вот так:

class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg);
};

template <class T1>
void myTest::funcOne(T1 arg)
{
        Serial.println(arg);
}

или это

class myTest
{
public:
    myTest();
    template <class T1>
    void funcOne(T1 arg)
    {
            Serial.println(arg);
    }
};
,

Не могли бы вы объяснить, чем это отличается от того, что я изначально написал в своем вопросе?, @Guy . D

шаблон является декларацией. источник, в котором вы используете шаблон, не может видеть его в cpp, @Juraj

На самом деле дублировать функцию в файле .h?, @Guy . D

Я пишу "двигаться". Это должно быть только в .h, @Juraj

Компиляторы не знают, какой класс использовать для шаблонного класса, если вы компилируете метод отдельно. Обычный способ — поместить реализацию метода в заголовок, чтобы компилятор мог создать конкретную реализацию., @the busybee

@thebusybee, есть myTest::, чтобы назначить метод классу, @Juraj

Извините, я забыл @Guy.D, которому был адресован комментарий., @the busybee

@thebusybee, я знаю, но Гай прав, @Juraj

@Guy.D, помогло?, @Juraj

@Juraj - сейчас проверено. ДА! большое спасибо, @Guy . D