#include <iostream>
using namespace std;
const string getFileNameAsVarName(string filename, int lineNo)
{
string s = "";
for (char c : filename)
{
if (c > 'a' && c < 'z')
{
s += c;
}
}
return s + to_string(lineNo);
}
#define DYNAMIC_NAME() (getFileNameAsVarName(__FILE__, __LINE__))
#define NAME() aaa
int main()
{
int NAME() = 123; // OK Expands to: aaa
int DYNAMIC_NAME() = 234; //Not OK Expands to:
// (getFileNameAsVarName("/Users/guichizhao/Documents/GitHub/learn/main.cpp", 29))
return 0;
}
它可能看起来很复杂,但我们有一个有效的用例。我们的目的是声明一个动态命名的变量,即变量名由文件名和行号决定,我们尝试通过使用宏来实现这一点,这似乎是我们实现目标的唯一机会。 问题是文件名不是合法的cpp变量名,如果我们使用cpp代码使其合法,则MACRO抱怨,在MACRO替换后,它不再有效,请参阅代码中的注释
那么,有什么方法可以解决这个困境,或者有其他方法来获取动态命名的变量吗?
另外,我们的项目中使用了CMake,不确定CMAKE是否可以提供帮助,任何与CMAKE相关的解决方案也非常感谢
从根本上来说你不能。
宏由 C++ 预处理器处理。它适用于代币。它可以将令牌转换为字符串 (FOO => "FOO"),但无法将字符串转换回令牌。正如您所发现的,
__FILE__
是一个字符串,而变量名称必须是不带引号的标记。
getFileNameAsVarName
是一个 C++ 函数,甚至 consteval
函数也会在 after 预处理器完全完成后运行。届时,所有代币都是最终的。