为何op_and构造函数无法找到?C++循环依赖问题排查
为何在
op.h中定义operator&正常,移到data.h就报构造函数匹配错误? 问题场景
当在op.h中定义op_and* operator&(data& left, data& right)时,代码可以正常运行:
/* data.h */ #ifndef _DATA_H #define _DATA_H #include <string> #include <utility> #include "node.h" #include "op.h" struct data: node{ std::string name; int width; }; #endif //_DATA_H /* op.h */ #ifndef _OP_H #define _OP_H #include <string> #include <utility> #include "node.h" #include "data.h" struct op: node { const std::string symbol; explicit op(data& left, data& right, std::string symbol): node(left, NODES::EMPTY, right), symbol(std::move(symbol)){} }; struct op_and: op{ explicit op_and(data& left, data& right): op(left, right, "&"){} }; op_and* operator&(data& left, data& right){ return new op_and(left, right); // 此处正常运行 } #endif //_OP_H
但将该operator&定义移到data.h中时,IDE会提示No matching constructor for initialization of "op_and":
/* data.h */ #ifndef _DATA_H #define _DATA_H #include <string> #include <utility> #include "node.h" #include "op.h" struct data: node{ std::string name; int width; }; op_and* operator&(data& left, data& right){ return new op_and(left, right); // 此处报错,无法找到op_and(data&, data&) } #endif //_DATA_H
原因分析:循环依赖的预编译过程
这是典型的循环依赖问题。当data.h中先包含op.h时,预编译的实际执行顺序如下:
#ifndef _DATA_H #define _DATA_H #include <string> #include <utility> #include "node.h" #ifndef _OP_H #define _OP_H /* 开始包含"op.h" */ #include <string> #include <utility> #include "node.h" #include "data.h" // 由于_DATA_H已定义,此处无内容引入 struct op: node { public: const std::string symbol; explicit op(data& left, data& right, std::string symbol): // 符号"data"尚未声明 node(left, NODES::EMPTY, right), symbol(std::move(symbol)){} }; struct op_and: op{ public: explicit op_and(data& left, data& right): // 符号"data"尚未声明 op(left, right, "&"){} }; #endif //_OP_H /* 结束包含"op.h" */ struct data: node{ std::string name; int width; }; op_and* operator&(data& left, data& right){ return new op_and(left, right); // 报错 } #endif //_DATA_H
此时struct op、struct op_and的定义均无效——因为它们依赖的data类型还未被声明。后续operator&中尝试调用op_and的构造函数时,编译器无法识别有效的op_and(data&, data&)构造函数,因此报错。
解决方案
调整头文件包含顺序,将#include "op.h"放到struct data的定义之后,确保op.h中的代码能看到完整的data类型定义:
#ifndef _DATA_H #define _DATA_H #include <string> #include <utility> #include "node.h" struct data: node{ std::string name; int width; }; #include "op.h" op_and* operator&(data& left, data& right){ return new op_and(left, right); } #endif //_DATA_H
内容的提问来源于stack exchange,提问作者Kera
相关产品推荐
相关产品推荐

