在C/C++中,是否有类似于#ifndef的指令用于typedef?

Zac*_*ner 44 c c++

如果我想仅在未定义值时定义值,我会执行以下操作:

#ifndef THING
#define THING OTHER_THING
#endif
Run Code Online (Sandbox Code Playgroud)

如果THINGtypedef'd标识符,并且未定义,该怎么办?我想做这样的事情:

#ifntypedef thing_type
typedef uint32_t thing_type
#endif
Run Code Online (Sandbox Code Playgroud)

问题出现了,因为我想检查外部库是否已经定义了boolean类型,但我愿意听一个更通用的解决方案.

Dav*_*eas 24

语言中没有这样的东西,也不需要.在单个项目中,您不应该使用相同的typedef别名来引用不同类型,因为这违反了ODR,如果您要为同一类型创建相同的别名,那么就这样做.该语言允许您根据需要多次执行相同的typedef,并且通常会捕获该特定ODR(在同一个翻译单元中):

typedef int myint;
typedef int myint;       // OK: myint is still an alias to int
//typedef double myint;  // Error: myint already defined as alias to int
Run Code Online (Sandbox Code Playgroud)

如果您打算通过使用typedef来确定使用哪种功能来实现不同类型的功能,那么您应该查看模板而不是typedef.

  • 不对.在编写库时,这很容易出现.当函数返回布尔值时,你在头文件中使用了什么?如果您的库在X项目中使用,那么X已经定义了BOOL.如果您在另一个项目中使用您的库,可能会有一个不同的,完全不兼容的Bool定义. (8认同)
  • 注意:仅供参考,对于 C 来说,多次声明 typedef 是无效的,即使它们都使用相同类型的别名。请参阅http://stackoverflow.com/a/8367810/816536 (2认同)

Alo*_*ave 20

C++没有提供任何代码来测试存在的机制,typedef你可以拥有的最好的东西是这样的:

#ifndef THING_TYPE_DEFINED
#define THING_TYPE_DEFINED
typedef uint32_t thing_type 
#endif
Run Code Online (Sandbox Code Playgroud)

编辑:
作为@David,他的评论是正确的,这回答如何?部分,但重要的是错过了原因?它可以通过上面的方式完成,如果你想要做到这一切,但重要的是你可能不需要这样做,@ David的答案和评论解释了细节,我认为这正确地回答了问题.

  • 那是*丑陋的*和*无用的*.重要的问题不是如何做到这一点,而是*为什么要这样做?*答案是你*不应该*.typedef可以在同一个翻译单元中重新定义多次(假设它总是别名相同),这样就不会有问题.将其定义为在同一程序的不同翻译单元中使用不同类型的别名是违反ODR的,因此您也不希望这样.如果别名总是相同的话,你可以获得的最好是***,或者*在编译时隐藏*一个错误,具体取决于之前包含的内容. (9认同)

iam*_*ind 8

在预处理阶段,C++中没有这样的工具.在最大可以做到

#ifndef thing_type
#define thing_type uint32_t 
#endif
Run Code Online (Sandbox Code Playgroud)

虽然这不是一个好的编码实践,但我不建议.

  • 我没有投票,但我更喜欢当人们告诉我答案有什么问题而不仅仅是一个downvote.这种方法的问题是`typedef`为该类型创建了一个真正的别名,而一个宏只是*text替换.在示例中它没关系,但是`void foo(const X x)`的语义是非常不同的,这取决于`X`是一个typedef还是上面的宏:`typedef int*X`将使函数`void foo(int*const)`,而`#define X int*`将使它成为`void foo(int const*)`(最左边的'const`!) (10认同)

Mik*_*our 6

预处理程序指令(例如#define)是粗略的文本替换工具,它们对编程语言一无所知,因此它们不能对任何语言级别的定义起作用.

确保类型仅定义一次有两种方法:

  • 构造代码以使每个定义都有其位置,并且不需要多个定义
  • #define预处理器宏与类型一起使用,并#ifndef在定义类型之前用于检查宏定义.

第一个选项通常会导致更易于维护的代码.如果你不小心在一个程序中最终得到了不同的类型定义,第二个可能会导致细微的错误.