C++ C++;预处理器确保全局唯一字符串

C++ C++;预处理器确保全局唯一字符串,c++,gcc,macros,c-preprocessor,C++,Gcc,Macros,C Preprocessor,我有一个宏函数,它有一个名称,可以从不同的名称空间调用。我希望确保此名称在全球范围内是唯一的。“定义”类似于以下内容: #define DECLARE_NEW_MYVAR( Name ) static MyVar Name( #Name ) #include <cstring> #include <iostream> #define COMMON_PATH_PREFIX "/home/user/path/to/project/" #define UNIQUE_IDE

我有一个宏函数,它有一个名称,可以从不同的名称空间调用。我希望确保此名称在全球范围内是唯一的。“定义”类似于以下内容:

#define DECLARE_NEW_MYVAR( Name ) static MyVar Name( #Name )
#include <cstring>
#include <iostream>

#define COMMON_PATH_PREFIX "/home/user/path/to/project/"

#define UNIQUE_IDENTIFIER() (__FILE__ + std::strlen(COMMON_PATH_PREFIX))

void someFunction(const char *identifier)
{
    std::cout << identifier << std::endl;
}

int main()
{
    someFunction(UNIQUE_IDENTIFIER());
}
我希望这个静态变量具有名称空间(这就是我希望从各种名称空间调用它的原因),但我还需要确保传递给MyVar的构造函数的字符串是全局唯一的。这是因为我要序列化这个值,我需要能够正确地将它关联回来

我尝试了几件没有成功的事情:

强制使其唯一:根据某些信息,在名称后附加某些内容以强制使其唯一

  • 使用
    \uuuu计数器\uuuu
    宏:我所针对的一个编译器没有此宏。此外,假设调用宏的顺序相同似乎很危险
  • 使用
    \uuuu FILE\uuuu
    宏:该宏具有完整的文件路径,这有助于确保其唯一性,但如果从不同的位置或不同的机器编译,反序列化将不再工作
要检查它是否唯一:让调用者决定它是否是全局唯一的,如果不是,让编译器抱怨

  • 我在寻找一种方法,从一个名称空间中声明全局名称空间中的某些内容,这样,如果它们不使其唯一,我至少可以导致一个多定义符号。我想不出一个办法
基本上,我需要拿出一个全局唯一的字符串来传递给我可以信任的MyVar,它在不同编译之间不会改变,最好在代码更改之间也不会改变(只要特定调用没有改变)


有人知道怎么做吗?

您可以像这样从
\uuuu文件\uuuu
中删除项目目录的前缀:

#define DECLARE_NEW_MYVAR( Name ) static MyVar Name( #Name )
#include <cstring>
#include <iostream>

#define COMMON_PATH_PREFIX "/home/user/path/to/project/"

#define UNIQUE_IDENTIFIER() (__FILE__ + std::strlen(COMMON_PATH_PREFIX))

void someFunction(const char *identifier)
{
    std::cout << identifier << std::endl;
}

int main()
{
    someFunction(UNIQUE_IDENTIFIER());
}
#包括
#包括
#定义公共路径前缀“/home/user/PATH/to/project/”
#定义唯一标识符()
void someFunction(常量字符*标识符)
{

std::cout您可以从
文件中删除项目目录的前缀,如下所示:

#define DECLARE_NEW_MYVAR( Name ) static MyVar Name( #Name )
#include <cstring>
#include <iostream>

#define COMMON_PATH_PREFIX "/home/user/path/to/project/"

#define UNIQUE_IDENTIFIER() (__FILE__ + std::strlen(COMMON_PATH_PREFIX))

void someFunction(const char *identifier)
{
    std::cout << identifier << std::endl;
}

int main()
{
    someFunction(UNIQUE_IDENTIFIER());
}
#包括
#包括
#定义公共路径前缀“/home/user/PATH/to/project/”
#定义唯一标识符()
void someFunction(常量字符*标识符)
{

std::cout
\uuuuu FILE\uuuuu
在任何情况下都不起作用,因为它会扩展为字符串常量,并且无法提取其内容。我认为您在这里遇到了麻烦。字符串常量就是我想要的(
\uuuu FILE\uuuu
将与MyVar参数的名称连接起来)。我不需要变量名本身是唯一的,因为它将位于自己的命名空间中。编译器将确保它在其命名空间中是唯一的。为什么不让您的
声明\u NEW\u MYVAR
将字符串作为第二个参数,它具有全局唯一性,如GUID。这将有助于使其稳定但唯一。我希望不要求此定义的使用者确保它是唯一的,或者至少能够让编译器验证它是唯一的。如果我使用第二个参数作为键,我仍然需要一种方法来确保它实际上是唯一的。那么,您真的需要字符串吗?例如,创建的对象的地址保证是非唯一的ique,您可以“免费”获取它。您可以将它快速转换为字符串:-)
\uuuu FILE\uuuu
在任何情况下都不起作用,因为它扩展为字符串常量,并且无法提取其内容。我认为您在这里遇到了麻烦。字符串常量是我想要的(
\uu FILE\uuuu
将与MyVar参数的名称连接在一起)。我不需要变量名本身是唯一的,因为它将位于自己的命名空间中。编译器将确保它在其命名空间中是唯一的。为什么不让您的
声明\u NEW\u MYVAR
将字符串作为第二个参数,它具有全局唯一性,如GUID。这将有助于使其稳定但唯一。我希望不要求此定义的使用者确保它是唯一的,或者至少能够让编译器验证它是唯一的。如果我使用第二个参数作为键,我仍然需要一种方法来确保它实际上是唯一的。那么,您真的需要字符串吗?例如,创建的对象的地址保证是非唯一的ique,你可以“免费”得到它。您可以将其快速转换为字符串:-)我认为这将是最好的解决方案。考虑到单个文件中会有多个声明,仍然有一些奇怪之处。相反,我决定在运行时验证字符串的唯一性。我认为这将是最好的解决方案。考虑到将有b我决定在运行时只验证字符串的唯一性。