2

我有一组松散相关的头库,我想让它们一起工作,而不是紧密耦合。我想到的一种方法是尝试包含其他头文件,如果找到它们,那么我可以相应地生成代码。所以也许我会在vector.hh中有一个向量类:

#ifndef __VECTOR_HH__
#define __VECTOR_HH__

bunch of vector-y stuff

#endif

然后在另一个文件中的 coordinates.hh (假设它进行坐标转换):

#ifndef __COORDINATES_HH__
#define __COORDINATES_HH__
#include <vector.hh>

class SomeCoordinateType {
#ifdef __VECTOR_HH__
    operator vector() { <convert to vector> }
#endif
}

#endif

这个想法是用户获取他们需要的任何头文件。如果他们获取了vector.hh 头文件以及coordinates.hh,那么我将为他们创建转换运算符,如果没有,我不这样做。这一切都取决于能否让#include 指令在失败时不会产生致命错误。有没有办法做到这一点?

4

2 回答 2

7

执行此操作的一种典型方法是使用小型配置工具生成自定义“config.h”(显然使用您认为合适的名称),其中仅包含他们选择的配置所需的其他标头。

另一种可能性是让 config.h 有条件地包含其他头文件,并让您的配置工具生成一个合适的 makefile,通过定义(或不​​)控制这些包含的宏来启用功能。通常,您将拥有一个定义实际依赖项的主 makefile,并且只需生成一个小文件以包含如下行:

特征 = -DCOORDS -DVECTOR

CFLAGS = $(特征)-O2

...然后将其包含到您的主 makefile 中以获取在编译期间定义的那些值,从而启用依赖于它们的功能。然后在你的标题中,你会有类似的东西:

// coordinates.h
#ifdef VECTOR
#include <vector>
#endif

// ...
class coordinate {
   #ifdef VECTOR
       operator vector() { /* ... */ }
   #endif
};

然而,我会努力避免让你的代码#ifdef到处塞满,尤其是嵌套到需要长时间和仔细分析才能确定一个类对于任何给定的特性组合具有哪些特性的地步。

于 2012-05-15T02:58:25.027 回答
3

根据 C 标准,编译器必须对丢失的标头进行诊断。

一旦它完成了,它就可以继续编译并生成一个它可以并且想要这样做的目标文件。另一方面,大多数情况下,缺少头文件会导致其他错误的主要列表(因为头文件对编译至关重要),因此不会生成目标文件。

由于缺少标头,编译器有权不生成目标文件,因此您不能可移植地假设除了失败之外的任何事情。失败是迄今为止最常见的结果。

(IIRC,曾经——可能是十年或更长时间前——Sun C 编译器生成了一条消息,#error但继续编译,有时成功,这取决于#error所保护的内容。此后已修复。不直接相同,但有些相关.)

于 2012-05-15T01:12:40.367 回答