【发布时间】:2017-10-18 10:04:15
【问题描述】:
给定一个类型、名称和默认值的列表,我可以很容易地编写一个工具来生成有效的 C++ 代码,该代码用每种类型、名称和默认值的成员变量声明一个类。例如,给定列表
- int, foo, 42
- 浮点数,条形,0.1f
(和类名“Baz”),它会生成
class Baz {
int foo = 42;
float bar = 0.1f;
}
如果一个工具可以生成这样一个类,编译器不能为我做吗?我正在考虑这些方面的事情(注意:这是伪代码):
template <typename ...MemberTypes> class Baz {
MemberTypes::type... MemberTypes::name... = MemberTypes::default...;
}
上面的类会被创建类似
using MyBaz = Baz<member_type<int, "foo", 42>, member_type<float, "bar", 0.1f>>;
这可能的原因:
- 所有必需的信息在编译时都可用。外部工具可以轻松完成。
- 可以用类似的方式 (Declare member variables from variadic template parameter) 创建一个使用元组而不是专用成员变量的类。
- 我可以使用模板特化对成员的有限组合进行近似。
- 模板元编程是图灵完备的 (C++ templates Turing-complete?),所以“一切”都应该是可能的。
不可能的原因:
- 模板参数不能是字符串字面量 (Passing a string literal as a parameter to a C++ template class),实际上,不能是整数。
- 我想不出这样做的方法(弱论点)。
如果可以,该怎么做?如果不可能,为什么不呢?即将到来的 c++17 在这方面有什么改变吗?
更新:示例问题:
通常,配置数据存储为字符串层次结构或其他形式的“任何类型”。然而,这会导致代码丑陋 (config.get<int>("core.timeout")) 并阻止编译器帮助解决拼写错误等问题 (config.get<int>("core.timeuot"))。
通过声明每个配置变量的真实类型,编译器可以检查类型并防止拼写错误。但是,需要自定义代码将配置数据读入正确的成员变量。如果添加了新的配置开关,很容易忘记更新这段代码。
只指定所有成员的类型和名称会很方便,然后让编译器自动生成类(包括读取配置文件的方法)。这是我要求的功能的一个可能用例。
【问题讨论】:
-
您是在问最新版本的 c++ 是否有可能,还是在问是否有可能在理论上的未来版本的 c++ 中做到这一点?
-
""一切"都应该是可能的。" 任何数学运算都可以用一个完整的巡演系统来表达。这并不意味着一切皆有可能。我想您可以为一种新语言编写一个编译器,该编译器支持您使用模板元编程实现的功能。
-
可能是这样的:
std::tuple<typename MemberTypes::type...> all_members = {MemberTypes::default...}; -
你通过写下它的定义来创建一个类。没有其他办法。您不能获取一段编译时数据并将其转换为具有模板魔法的类。您需要源代码中存在语法和语义上有效的类定义。为什么需要生成类?为什么
std::tuple不是可行的替代品? -
关于 "
member_type<float, "bar", 0.1f>"。floatc++ 不支持模板参数。有关允许的非类型模板参数类型的列表,请参阅here。
标签: c++ templates c++14 template-meta-programming c++17