Why it is okay when define op_and* operator&(data& left, data& right)
in op.h
/* 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); // it is okay here
}
#endif //_OP_H
But when define it data.h
, IDE hints 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); // here is error, cannot find op_and(data&, data&)
}
#endif //_DATA_H
This does look like a Circular dependency problem. I made a mistake. When I tried to include op.h
in data.h
, I get something like:
#ifndef _DATA_H
#define _DATA_H
#include <string>
#include <utility>
#include "node.h"
#ifndef _OP_H
#define _OP_H
/* including "op.h" starts */
#include <string>
#include <utility>
#include "node.h"
#include "data.h" // this will introduce nothing because _DATA_H is already defined
struct op: node {
public:
const std::string symbol;
symbol(std::move(symbol)){}
explicit op(data& left, data& right, std::string symbol): // symbol "data" has not been declared yet
node(left, NODES::EMPTY, right), symbol(std::move(symbol)){}
};
struct op_and: op{
public:
explicit op_and(data& left, data& right): // symbol "data" has not been declared yet
op(left, right, "&"){}
};
#endif //_OP_H
/* including "op.h" ends */
struct data: node{
std::string name;
int width;
};
op_and* operator&(data& left, data& right){
return new op_and(left, right); // error
}
#endif //_DATA_H
Now, definitions of struct op
, struct op_and
, and method operator&
are in-valid since symbol data
has not been declared.
So, if I put #include "op.h"
after the definition of struct node
, things work fine.
#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