Делаю универсальный шаблон контейнера, чтобы хранил объекты не только в памяти и чтобы работал с ‘Range-based for loop’ (то есть в стиле for(auto i : items)). Код еще не закончен, хочу разобраться с ошибкой, что-то никак не пойму
Имею базовый класс (шаблон):
некий производный класс Container
И импликация для контейнера с памятью:
Вызов где-то в майне:
Самое смешное, что когда удаляю (комментю) функции begin() и end() из IContainer, ошибка необъяснимо пропадает (вернее она появилась, когда я добавил эти функции).
Код файла main.cpp целиком (для копи-паста):

2 ответа 2
На самом деле, удивительно и странно не то, что эта ошибка появилась когда вы добавили begin и end в базовый класс — а то, что без них все работает.
Видимо, виноваты чудеса оптимизации, выкинувшие нерабочий код.
Посмотрим внимательнее на этот метод — настоящая ошибка в нем:
Здесь класс OuterIterator приводится к своему предку. Но в C++ полиморфизм доступен только для ссылок и указателей, а не для значений! Без оператора приведения типа этот код работать не должен.
Обычно решают эту проблему следующим образом — вводят промежуточное звено, для которого доступен полиморфизм.
То есть вводится, к примеру, класс IContainer::iterator , являющаяся общим для всех классов «фротэндом» — и абстрактный класс IContainer::IIterator , скрывающий детали реализации.
Первый класс держит указатель на второй:
Однако, такой способ может привести к просадке производительности если тип контейнера хорошо известен — виртуальные вызовы обходятся не бесплатно.
Поэтому в финальном классе-наследнике есть смысл продублировать итератор, чтобы он использовал уже конкретную реализацию. Это можно сделать при помощи шаблонов (т.н. статический полиморфизм):
В таком случае, классы IContainer и Container смогут выглядеть примерно так:
#include // Подключение библиотек
#include
DS1302 rtc(2, 3, 4); // Инициализация библиотеки с указанием
DS1302 myGLCD(8,9,10,11,12); // пинов подключения к Arduino
extern uint8_t TinyFont[]; // Объявление трех внешних
extern uint8_t SmallFont[]; // массивов символов
extern uint8_t BigNumbers[];
Time t; // Инициализация структуры
void setup()
<
myGLCD.InitLCD(); // Инициализация дисплея
rtc.halt(false); // Установка режимов
rtc.writeProtect(false); // работы часов
// Следующих три строки нужно закомментировать после
// установки времени и загрузить скетч в плату повторно
rtc.setDOW(MONDAY); // Установка дня недели
rtc.setTime(10, 59, 10); // Установка времени 10:59:10
rtc.setDate(20, 7, 2013); // Установка даты 20 июля 2013
>
void loop()
<
t = rtc.getTime(); // Получение времени и его запись в структуру t
myGLCD.setFont(BigNumbers); // Установка набора символов
myGLCD.clrScr(); // Очистка экрана
myGLCD.printNumI(int(t.hour), 7, 0); // Вывод часов
myGLCD.print(«-«, 35, 0);
myGLCD.printNumI(int(t.min), 49, 0); // Вывод минут
myGLCD.setFont(SmallFont); // Установка набора символов
myGLCD.printNumI(int(t.sec), CENTER, 0); // Вывод секунд
myGLCD.print(rtc.getDOWStr(), CENTER, 25); // Вывод дня недели
myGLCD.print(rtc.getDateStr(), CENTER, 33); // Вывод даты
myGLCD.setFont(TinyFont); // Установка набора символов
myGLCD.print(«HELLO WORLD», CENTER, 42);
myGLCD.update(); // Вывод вместимого буфера на дисплей
delay (1000); // Задержка 1 с
>
#include // Подключение библиотек
#include
DS1302 rtc(2, 3, 4); // Инициализация библиотеки с указанием
DS1302 myGLCD(8,9,10,11,12); // пинов подключения к Arduino
extern uint8_t TinyFont[]; // Объявление трех внешних
extern uint8_t SmallFont[]; // массивов символов
extern uint8_t BigNumbers[];
Time t; // Инициализация структуры
Today, I got a rather weird C++ error. That is. My code is very simply doing a search using the std::find() function as follow:
Yet, it would not compile that simple line of code.
Clearly, I use the begin() and end() of the same vector, and I use a value which is exactly what the vector is made of (we see that in the first line of error below: the std::vector<> T parameter is a basic string, which is what column_name is.)
Looking at the error, we see that it says that it’s just not compatible. It expects an std::istreambuf_iterator . Why would C++ tell me that such a type is required when I used a parameter to the function which is an std::vector .
If you think that this error is not talkative, welcome to the club! It took me a moment to find the reason for the problem.
Solution
The fact is that this problem is caused by the missing definition of the default std::find() function. What was needed in that C++ file was a #include of the algorithms. The following:
In fact, I had the input stream included, so the following:
And it looks like they have a specialization of the std::find() algorithm for one to search through it stream buffer. That definition gets picked up if you have only that one include.
By adding the other include, now C++ is capable of finding a matching std::find() and compiles my file happily.
If you’re interested about finding the list of routes on your Linux OS using a C++ class, I have that in my libaddr library.