你能使增量编译器保持常量吗?
虽然听起来荒谬…..
我想要一个常量,每次使用它时它会增加1
int x; int y; x = INCREMENTING_CONSTANT; y = INCREMENTING_CONSTANT;
其中x == 1; 和y == 2
注意我不想要y = INCREMENTING_CONSTANT + 1类型的解决方案。
基本上我想将它用作编译时唯一ID(通常它不会在代码中使用,例如在另一个宏中)
它不是标准的,但有些编译器支持__COUNTER__
宏。 请参阅有没有人曾使用__COUNTER__预处理器宏?
您可以使用Boost.Preprocessor(与C一起使用)和BOOST_PP_COUNTER
将某些内容组合在一起
文档页面上给出的示例:
#include BOOST_PP_COUNTER // 0 #include BOOST_PP_UPDATE_COUNTER() BOOST_PP_COUNTER // 1 #include BOOST_PP_UPDATE_COUNTER() BOOST_PP_COUNTER // 2 #include BOOST_PP_UPDATE_COUNTER() BOOST_PP_COUNTER // 3
翻译成你想要的
#include int x = BOOST_PP_COUNTER; // 0 #include BOOST_PP_UPDATE_COUNTER() int y = BOOST_PP_COUNTER;// 1 #include BOOST_PP_UPDATE_COUNTER() int z = BOOST_PP_COUNTER; // 2
您也可以使用插槽(稍微更灵活,代价是比上述解决方案更多的代码):
#include #define BOOST_PP_VALUE 0 //ensure 0 to start #include BOOST_PP_ASSIGN_SLOT(1) int a = BOOST_PP_SLOT(1); //0 #define BOOST_PP_VALUE 1 + BOOST_PP_SLOT(1) #include BOOST_PP_ASSIGN_SLOT(1) int b = BOOST_PP_SLOT(1); //1
如果您只需要一些唯一的ID ish ,您可以使用__LINE__
预处理器符号吗? 这不是你要求的,但它可能适合你的目的。
在我的情况下,我希望每个子系统都有一个系统范围的唯一密钥,但子系统的选择取决于使用系统的人。 这些需要是8位值,因为它针对的是嵌入式系统。
这就是我刚才提出的:
#define LAST_KEY -1 // SUB1_KEY definition enum { SUB1_KEY_ORIGIN = LAST_KEY, SUB1_KEY, }; #undef LAST_KEY #define LAST_KEY SUB1_KEY // SUB2_KEY definition enum { SUB2_KEY_ORIGIN = LAST_KEY, SUB2_KEY, }; #undef LAST_KEY #define LAST_KEY SUB2_KEY // SUB3_KEY definition enum { SUB3_KEY_ORIGIN = LAST_KEY, SUB3_KEY, }; #undef LAST_KEY #define LAST_KEY SUB3_KEY // ....
挑战在于确保每次都以相同的顺序编译引入每个块的包含链。
我经常希望编译时变量。 但是,最简单的方法就是为每个人定义常量。
如果您使用的是C而不是C ++,那么在我的线程问题上面的答案可以通过在某个全局状态类中使用functionoid或类似的解决方案来解决。
您也可以尝试使用xmacro。 创建一个新文件,我们称之为xmacro.h
INCREMENTING_CONSTANT; #define INCREMENTING_CONSTANT INCREMENTING_CONSTANT + 1
然后,在标准标题中,
#define INCREMENTING_CONSTANT 0 #define USE_INCREMENTING_CONSTANT #include "xmacro.h" const int x = USE_INCREMENTING_CONSTANT
我没有测试过这个,但xmacros有一些常规宏无法使用的强大function,比如defs / undefs,而我的直觉说它应该可行。 预处理器function强大,但相当愚蠢,因此可能会失败。
那么,它不是常数,是吗? ;)
您可以使用以下function执行此操作:
int id() { static int i = 0; return ++i; } x = id(); y = id();
如图所示,这不是线程安全的。 要做到这一点,您需要使用互斥锁保护它,或使用编译器/平台特定的primefaces增量器。
你想让x
和y
自己成为常数吗? 如果是这样,最简单和最干净的事情可能是使用匿名枚举:
enum { x = 1, y /* Add new ones here. */ };
这意味着您只需要为该列表添加一个新名称,它将被赋予下一个整数值。 这是一个有用的技巧,你不关心值是什么(运行时之外),只要它们是不同的。 例如,在为GUI中的控件分配标识符时,您经常会看到:
enum { button1_id = FIRST_USER_ID, button2_id, combo_id, ... }
一些GUI框架提供了一个GetUserId()函数,它将生成一个新函数(使用内部静态变量); 但我认为这发生在运行时。 看到如此多的呼号连续播出也有点乏味。
button1_id = GetUserId(); button2_id = GetUserId(); combo_id = GetUserId(); ...
“递增常数”是矛盾的。 你不能在编译时这样做。
这是实现它的一种丑陋方式。
static int _counter=0; #define INCREMENTING_CONSTANT (_counter++)