вектор структур, выдающий ошибку «не объявлено в этой области»

#c #data-structures #vector #struct #initialization

#c #структуры данных #вектор #структура #инициализация

Вопрос:

У меня есть структура, объявленная следующим образом:

 #ifndef PLAYLIST_H
#define PLAYLIST_H
#include <iostream>
#include <string>
#include <vector>
#include "playlistitem.h"
#include "song.h"
#include "time.h"
struct Playlist {
    std::vector<Song> songs;
    Time cdTotalTime;
    int totalTime;
};
  

и структурная композиция, объявленная в другом файле:

 #ifndef SONG_H
#define SONG_H
#include "playlist.h"
#include "time.h"
struct Song {
    std::string title;
    std::string artist;
    std::string album;
    int track;
    Time length;
};
  

У меня есть оба определения структуры в заголовках, и оба #включены, как и должны быть.

При компиляции я получаю ошибку в

 std:vector<Song> songs;
  

ошибка ‘Song’ не была объявлена в этой области

Чего мне не хватает?

Комментарии:

1. Вы уверены, что включили Song файл определения в файл, определяющий Playlist ? И что это в том же пространстве имен?

2. Как вы «включаете их так, как они должны быть»? (Подсказка: это не так 😉 )

3. Пожалуйста, покажите нам файл, в котором вы используете определения.

Ответ №1:

playlist.h включает song.h

song.h НЕ должен включать playlist.h

Защита заголовка предотвращает бесконечную рекурсию, они не исправляют циклические зависимости.

В настоящее время song.h включает playlist.h. Затем, когда playlist.h включает song.h, ничего не происходит (из-за защиты заголовка) и Song не определяется. Таким образом, playlist.h выдает ошибки.

Ответ №2:

Не только ваш основной файл, но и файл, в котором Playlist объявлен, также должен #включать файл, в котором Song находится.

Ответ №3:

Определение Song должно предшествовать его использованию в определении Playlist . Поскольку они находятся в разных заголовках, вы должны убедиться, что заголовок для Playlist включает в себя заголовок Song , и оба имеют надлежащие заголовочные ограждения.

Ответ №4:

Ваши заголовки включают друг друга циклическим образом. Это бесполезно и ненужно. Почему вы song.h включаете playlist.h ? Удалите #include "playlist.h" из song.h , и это должно исправить ошибку.

Ответ №5:

Вы могли бы создать прототип Song в своем заголовке, поместив struct Song; и просто включив заголовок в свой.c/.cpp файл. Это дает бонус в виде более быстрого времени компиляции! 😀

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

Кроме того, я не вижу #endif в вашем коде. Прямо сейчас я предполагаю, что ваш код действительно имеет это;)