我需要改变我在正在处理的大型项目中包含标题的方式。我能够用较小的单个程序模拟我目前得到的错误。
举例来说,以下编译:
#include <map>
class C;
class A {
public:
C& add();
std::map<int,C> Cmap;
void dosomethingwithC();
};
class B {
public:
A& add();
std::map<int,A> Amap;
};
class C {
public:
B& add();
std::map<int,B> Bmap;
};
int main()
{
C c;
auto& emplacedB = c.add();
auto& emplacedA = emplacedB.add();
auto& emplacedC = emplacedA.add();
emplacedC.add();
return 0;
}
C& A::add()
{
auto emplace_results = Cmap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
auto& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;
}
B& C::add()
{
auto emplace_results = Bmap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
//auto& emplaced_pair = *pair_iterator;
std::pair<const int,B>& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;
}
A& B::add()
{
auto emplace_results = Amap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
auto& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;;
}
void A::dosomethingwithC()
{
Cmap[3].add();
}
但是,如果我将A
的函数定义移近A
,则以下内容不会编译:
#include <map>
class C;
class A {
public:
C& add();
std::map<int,C> Cmap;
void dosomethingwithC();
};
C& A::add()
{
auto emplace_results = Cmap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
auto& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;
}
class B {
public:
A& add();
std::map<int,A> Amap;
};
class C {
public:
B& add();
std::map<int,B> Bmap;
};
int main()
{
C c;
auto& emplacedB = c.add();
auto& emplacedA = emplacedB.add();
auto& emplacedC = emplacedA.add();
emplacedC.add();
return 0;
}
B& C::add()
{
auto emplace_results = Bmap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
//auto& emplaced_pair = *pair_iterator;
std::pair<const int,B>& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;
}
A& B::add()
{
auto emplace_results = Amap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
auto& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;;
}
void A::dosomethingwithC()
{
Cmap[3].add();
}
即使宣布class C
,我也会收到错误消息。该错误说明std::pair
使用 undefined class C
。
构造标题的正确方法是什么,包括进行编译?
答案 0 :(得分:1)
在这个特定实例中,如果所有.cpp文件都包含所有声明,那么关于缺失定义的错误(对于std::pair
,作为std::map
的一部分)就会消失。 (A需要C,但C需要B)
因此即使错误是针对缺失的定义,也可以通过包含声明来解决。我不确定为什么会发布separate question。
A.H
#ifndef A_h
#define A_h
#include <map>
class C;
class A {
public:
C& add();
std::map<int,C> Cmap;
void dosomethingwithC();
};
#endif
B.h
#ifndef B_h
#define B_h
#include <map>
class A;
class B {
public:
A& add();
std::map<int,A> Amap;
};
#endif
C.h
#ifndef C_h
#define C_h
#include <map>
class B;
class C {
public:
B& add();
std::map<int,B> Bmap;
};
#endif
A.cpp
#include "A.h"
#include "B.h" // also required here
#include "C.h"
C& A::add()
{
auto emplace_results = Cmap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
auto& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;
}
void A::dosomethingwithC()
{
Cmap[3].add();
}
B.cpp
#include "A.h"
#include "B.h"
#include "C.h" // also required here
A& B::add()
{
auto emplace_results = Amap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
auto& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;;
}
C.cpp
#include "A.h" // also required here
#include "B.h"
#include "C.h"
B& C::add()
{
auto emplace_results = Bmap.emplace(std::piecewise_construct,
std::forward_as_tuple(3),
std::forward_as_tuple());
auto pair_iterator = emplace_results.first;
//auto& emplaced_pair = *pair_iterator;
std::pair<const int,B>& emplaced_pair = *pair_iterator;
auto& map_value = emplaced_pair.second;
return map_value;
}
Main.cpp的
#include "A.h"
#include "B.h"
#include "C.h"
int main()
{
C c;
auto& emplacedB = c.add();
auto& emplacedA = emplacedB.add();
auto& emplacedC = emplacedA.add();
emplacedC.add();
return 0;
}