引用含其他函数的头文件中结构体时编译报错,如何解决?
std::vector<People*>编译错误:People wasn't declared in this scope 问题场景
你在usefulFunctions.h中定义了People结构体,同时包含无关的isNoItemsInBag()函数;在shoppers.h中尝试声明std::vector<People *> shoppersToday时,遇到以下编译错误:
template argument 1 is invalid
std::vector<People*> shoppersToday;
People wasn't declared in this scope
即使已经在shoppers.h中添加#include "usefulFunctions.h",问题依然存在。
问题根源:头文件循环引用
从你提供的代码可以看到,两个头文件存在循环依赖:
usefulFunctions.h中包含#include "shoppers.h"shoppers.h中又包含#include "usefulFunctions.h"
当编译器处理shoppers.h时,会先展开usefulFunctions.h,而usefulFunctions.h又会尝试展开shoppers.h——但由于你已经添加了头文件保护(#ifndef ... #define ... #endif),第二次展开shoppers.h会被跳过。此时编译器回到usefulFunctions.h的代码,People结构体的定义在#include "shoppers.h"之后,所以当shoppers.h里的std::vector<People *>被处理时,编译器还没有看到People的定义,因此报错。
解决方案:添加前向声明
你在shoppers.h的#include语句后添加struct People;前向声明的方式是完全正确的:
// shoppers.h #ifndef SHOPPERS_H #define SHOPPERS_H #include "usefulFunctions.h" struct People; // 前向声明 class Shoppers{ std::vector<People *> shoppersToday; }; #endif
因为std::vector<People*>只需要知道People是一个结构体类型(不需要完整的定义),前向声明就足够满足编译器的需求,同时打破了循环引用导致的定义顺序问题。
另外,建议你梳理一下头文件的依赖关系:如果People结构体里只需要Shoppers的指针,那么usefulFunctions.h里也不需要包含shoppers.h,而是用struct Shoppers;前向声明即可,这样可以彻底避免循环引用的问题:
// usefulFunctions.h #ifndef USEFULFUNCTIONS_H #define USEFULFUNCTIONS_H struct Shoppers; // 替换#include "shoppers.h" void isNoItemsInBag(); struct People{ Shoppers * shoppee; }; #endif
内容的提问来源于stack exchange,提问作者user7999116

