我有一些源自DSL的代码,需要为C ++调用者进行翻译。我需要弄清楚如何在C ++中对#include依赖项进行排序。幸运的是,我有一些限制可以使我的任务更容易:
但是,我必须转换一些描述合法C ++程序的代码,但是永远无法定义,例如
struct X {
Y y;
Y func();
};
struct Y {
X func();
};
// or
struct Y {
void func(X x);
};
struct X {
void func(Y y);
};
到目前为止,我提出了这样的想法,即我会将每个类型设置为自己的独立头,然后在实现文件中,我可以#include实现所依赖的所有类型,这不会太过难。问题是我如何能够破坏X和Y的代码,以便这是可能的。
现在,我已经考虑过应用RVO和NRVO,并为参数做一些类似的事情。但是,是不是有些情况下他们不仅没有真正的优化,而且实际上不可能?这是用MSVC10编写的,所以我可以处理C ++ 0x在这里提供的任何其他功能。
编辑:我编辑了我的代码,因为我略微低估了我的需求。 RVO和NRVO也无法削减这一点。
编辑编辑:我想,如果前向声明对于函数返回值和参数就足够了,我可以拓扑排序数据成员的包含顺序。毕竟,做
之类的事情仍然不合法struct X {
Y y;
};
struct Y {
X x;
};
答案 0 :(得分:1)
为什么不使用前向声明?
如果以这种方式声明X和Y,那么你的例子就完全可以了:
struct Y;
struct X {
Y func();
};
struct Y {
X func();
};
您可以将每个类型声明放入其自己的标头中,通过声明中使用的每种类型的前向声明进行前置,然后在实现文件中包含所有使用类型的标头。如果您转发声明类型声明中使用的每个类型,则不再需要担心首先要包含哪个文件。没关系。
总结一下:
headerA.h
#pragma once
class B;
class A {
B b;
public:
void myfunc();
};
headerB.h
#pragma once
class A;
class B {
A a;
};
implA.cpp
#include "headerA.h"
#include "headerB.h"
void A::myfunc() {
// ...
}
这种方式在不相关的代码中使用A类时,您必须同时包含headerA.h
和headerB.h
。如果您只想在使用类型A时包含headerA.h
,请按以下方式调整标题:
headerA.h
#pragma once
class B;
#include "headerB.h"
class A {
B b;
public:
void myfunc();
};
headerB.h
#pragma once
class A;
#include "headerA.h"
class B {
A a;
};
包容警卫将负责其余的工作。
答案 1 :(得分:1)
拓扑排序是要走的路。
如果这不起作用,您需要使用shared_ptr或放宽排序约束的东西来转换代码。
答案 2 :(得分:0)
按地址传递参数,或者创建一个不依赖于X或Y的中间数据类型并传递它。你真的无法避免返回/传递值问题,因为大小/接口不可用。因为它们是共同依赖的。
我想另一种选择是在同一个类接口中声明它们。
你可以使用模板和专业化......但除非你愿意编写定义,否则维护可能会很麻烦,而且生成器为此提供了一个选项。