gpt4 book ai didi

c++ - 编译时元编程,带字符串文字

转载 作者:行者123 更新时间:2023-11-28 08:29:51 24 4
gpt4 key购买 nike

我正在编写一些代码,这些代码实际上可以用一些简单的编译时元编程来完成。通常的做法是使用空结构标记作为编译时符号。我需要用一些运行时配置元素来装饰标签。静态变量似乎是唯一的方法(启用元编程),但是静态变量需要全局声明。为了回避 Scott Myers 的建议(来自 Effective C++ 第三版),我想到了通过在函数内部声明静态变量而不是类变量来对静态变量的初始化进行排序。

所以我想出了下面的代码,我的假设是它会让我有一个编译时符号,其中包含在运行时可用的字符串文字。我没有遗漏任何我希望的东西,只要我在初始化依赖模板类之前填充运行时字段,它就能正常工作? .

#include <string>

template<class Instance>

class TheBestThing {
public:
static void set_name(const char * name_in) {
get_name() = std::string(name_in);
}
static void set_fs_location(const char * fs_location_in) {
get_fs_location() = std::string(fs_location_in);
}
static std::string & get_fs_location() {
static std::string fs_location;
return fs_location;
}
static std::string & get_name() {
static std::string name;
return name;
}
};
struct tag {};
typedef TheBestThing<tag> tbt;

int main()
{
tbt::set_name("xyz");
tbt::set_fs_location("/etc/lala");

ImportantObject<tbt> SinceSlicedBread;
}

编辑:制作社区 wiki。

最佳答案

我终于明白问题出在哪里了......而你的解决方案并没有解决多少问题,如果有的话。

使用局部静态变量的目的是在首次使用时提供初始化,从而避免“Initialization Order Fiasco”(顺便说一句,它不解决“Destruction Order Fiasco”)。

但是对于您的设计,如果您有效地防止了崩溃,您并没有阻止在使用变量值之前使用变量的问题。

ImportantObject<tbt> SinceSliceBread; // using an empty string

tbt::set_name("xyz");

比较下面的用法:

std::string& tbt::get_name() { static std::string MName = "xyz"; return MName; }

这里 name 不仅被创建,而且在第一次使用时被初始化。使用未初始化的名称有什么意义?

好吧,既然我们知道您的解决方案行不通,让我们考虑一下。事实上,我们希望将其自动化:

struct tag
{
static const std::string& get_name();
static const std::string& get_fs_location();
};

(可能有一些访问器来修改它们)

我的第一个(也是简单的)解决方案是使用宏(但不是类型安全的):

#define DEFINE_NEW_TAG(Tag_, Name_, FsLocation_)              \
struct Tag_ \
{ \
static const std::string& get_name() { \
static const std::string name = #Name_; \
return name; \
} \
static const std::string& get_fs_location() { \
static const std::string fs_location = #FsLocation_; \
return fs_location; \
} \
};

对于您的情况,另一种解决方案可能是使用 boost::optional 来检测该值尚未初始化,并推迟依赖它的值的初始化。

关于c++ - 编译时元编程,带字符串文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2652164/

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