> int,foo,42
> float,bar,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).
>我可以使用模板特化来对有限的成员组合进行近似.
>模板元编程是turing-complete(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”)) ).
通过使用其真实类型声明每个配置变量,编译器可以检查类型并防止拼写错误.但是,需要使用自定义代码将配置数据读入正确的成员变量.如果添加了新配置开关,则很容易忘记更新此代码.
解决方法
然而,预处理器可以以有限的方式做到这一点,(在Boost.PP的帮助下,它使得它的标签)可以让我们编写以下内容(直接取自another answer of mine):
#define GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_0(...) \ ((__VA_ARGS__)) GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_1 #define GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_1(...) \ ((__VA_ARGS__)) GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_0 #define GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_0_END #define GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_1_END // Double the parentheses of a Boost.PP sequence // I.e. (a,b)(c,d) becomes ((a,b))((c,d)) #define GLK_PP_SEQ_DOUBLE_PARENS(seq) \ BOOST_PP_CAT(GLK_PP_DETAIL_SEQ_DOUBLE_PARENS_0 seq,_END) #define MAKE_ONE_VARIABLE(r,data,elem) \ BOOST_PP_TUPLE_ELEM(0,elem) BOOST_PP_TUPLE_ELEM(1,elem) = BOOST_PP_TUPLE_ELEM(2,elem); #define MAKE_CLASS(className,members) \ struct className { \ BOOST_PP_SEQ_FOR_EACH(MAKE_ONE_VARIABLE,~,GLK_PP_SEQ_DOUBLE_PARENS(members)) \ }
……并按原样使用它:
MAKE_CLASS(Baz,(int,42)(float,0.1f));
…扩展到:
struct Baz { int foo = 42; float bar = 0.1f; };