gpt4 book ai didi

c++ - 编译时使用自省(introspection)

转载 作者:太空宇宙 更新时间:2023-11-04 13:58:15 27 4
gpt4 key购买 nike

一段时间以来,我一直在尝试解决这个问题,到目前为止,每个人都告诉我这在我身边是不可能的,所以我想尝试一下。

这就是问题所在:人们使用环境变量,但没有正确地测试结果或默默地使用硬编码替代方案。

我想做的是想出一个小库,人们可以使用它来代替 getenv,它可以在初始化时通知用户环境。程序可能使用的变量。这仅意味着为此调用替换 getenv 并在可执行文件或库的初始化时放置单个函数调用(我不会处理动态环境。变量名制作,例如使用构造的字符串)。

这是我能够制作的一个简单示例 ( http://ideone.com/Wi1JBq )

#include <iostream>
#include <vector>

using namespace std;

static vector<string> test;

template <char const *str>
struct EnvVar
{
EnvVar()
{
test.push_back(string(str));
}
const char* GetEnvVarName() const
{
return str;
}
};

static void checkVars()
{
for(unsigned int i = 0; i < test.size(); i++)
cout << "Predefined : " << test[i] << endl;
}

#define GENERATE_ENV_VAR(Name) char _##Name[] = #Name; static EnvVar<_ ## Name> Name;

// ----- What is actually in the user file -----

GENERATE_ENV_VAR(FirstEnvVar)
GENERATE_ENV_VAR(SecondEnvVar)
GENERATE_ENV_VAR(ThirdEnvVar)

int main()
{
checkVars();
cout << "Usage : " << FirstEnvVar.GetEnvVarName() << endl;
cout << "Usage : " << SecondEnvVar.GetEnvVarName() << endl;
cout << "Usage : " << ThirdEnvVar.GetEnvVarName() << endl;
return 0;
}

这输出

Predefined : FirstEnvVar
Predefined : SecondEnvVar
Predefined : ThirdEnvVar
Usage : FirstEnvVar
Usage : SecondEnvVar
Usage : ThirdEnvVar

这样做的原因很明显,宏在全局级别使用,它在进入 main 之前初始化,这就是为什么第一个函数调用知道它们的原因。我想做的是没有那些,所以基本上,有这个:

int main()
{
checkVars();
cout << "Usage : " << FirstEnvVar.GetEnvVarName() << endl;
cout << "Usage : " << SecondEnvVar.GetEnvVarName() << endl;
cout << "Usage : " << ThirdEnvVar.GetEnvVarName() << endl;
return 0;
}

并得到相同的输出。我敢肯定它会涉及很多模板/宏黑客攻击,但它会很棒。我不希望只拥有一个解析代码和生成代码的脚本,但我知道这可能是一个解决方案。如果可能的话,我想要纯 C++,boost 就可以了。

谢谢。

最佳答案

为什么一定要是模板类呢?你应该能够通过 #NAME进入接受 const char * 的构造函数.在到达您在 main 中的代码之前,运行时将调用所有文件范围变量实例的构造函数.

class EnvVar
{
private:
const char *const str;

public:
static vector<string> env_vars;

EnvVar(const char *str_) : str(str_)
{
env_vars.push_back(string(str_)); // this vector seems redundant...
}
const char* GetEnvVarName() const
{
return str;
}
};

#define GENERATE_ENV_VAR(Name) EnvVar Name##_( #Name );

GENERATE_ENV_VAR(FirstEnvVar)
GENERATE_ENV_VAR(SecondEnvVar)
GENERATE_ENV_VAR(ThirdEnvVar)

您还会注意到我将下划线移到了变量名的末尾,因为前导下划线后跟大写字母是为编译器保留的。

另外,vector<string>似乎是多余的。拥有 EnvVar 的中央注册表实际上可能更有意义类注册自身的指针,如下所示:

class EnvVar
{
private:
const char *const str;

public:
static vector<class EnvVar *> registry;

EnvVar(const char *str_) : str(str_)
{
registry.push_back(this); // register ourselves
}
const char* GetEnvVarName() const
{
return str;
}
};

然后您始终可以通过遍历 EnvVars::registry 遍历完整的环境变量注册表。 .

关于c++ - 编译时使用自省(introspection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20436923/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com