d组合结构
原文
题目:
template AFields() {int a;}
struct A { mixin AFields; }
template BFields() {int b;}
struct B { mixin BFields; }
struct AB { mixin AFields; mixin BFields; }
A a; a.a = 1;
B b; b.b = 2;
AB ab; ab.a = 3; ab.b = 4;
如何编写连接构
,来编译.这里不控制A与B
,也没有AFields/BFields
.
struct A { int a; }
struct B { int b; }
mixin CatStruct!("AB", A, B);//这里.
AB ab;
ab.a = 1; ab.b = 2;
1命名元组
import std.meta, std.traits, std.typecons;
// 交织
template Interleave(A...)
{
static if(A.length == 0)
alias A Interleave;
else
alias AliasSeq!(A[0], A[A.length/2],
Interleave!(A[1..A.length/2], A[A.length/2+1..$])) Interleave;
}
// 帮助函数
template FieldTypeNameTuple(A)
{
alias Interleave!(Fields!A, FieldNameTuple!A) FieldTypeNameTuple;
}
template CatStruct(A...)
{
alias Tuple!(staticMap!(FieldTypeNameTuple, A)) CatStruct;//静映射
}
// 用法
struct A { int a; }
struct B { int b; }
struct C { int c; }
alias CatStruct!(A, B, C) ABC;
使用代理
import std.typecons;
struct A { int a; }
struct B { int b; }
struct AB
{
mixin MultiProxy!(A, B);
}
mixin template MultiProxy(A, B) {
private A _a;
private B _b;
mixin Proxy!_a aProxy;
mixin Proxy!_b bProxy;
template opDispatch(string op) {
static if (is(typeof(aProxy.opDispatch!op))) {
alias opDispatch = aProxy.opDispatch!op;
}
else {
alias opDispatch = bProxy.opDispatch!op;
}
}
}
unittest
{
AB ab;
ab.a = 4;
ab.b = 5;
assert(ab.a == 4);
assert(ab.b == 5);
}
标准库方法
mixin template CatStruct(string name, T...) {
//连接构
static import std.traits, std.conv;
private string _code_generator() {
string code = "struct " ~ name ~ " {";
foreach(oidx, t; T) {
foreach(idx, field; std.traits.FieldTypeTuple!t)
// 怪物行.
code ~= "std.traits.FieldTypeTuple!(T["~std.conv.to!string(oidx)~"])["~std.conv.to!string(idx)~"] "~ std.traits.FieldNameTuple!t[idx] ~ ";";
}
code ~= "}";
return code;
}
mixin(_code_generator());
}
使用FieldTypeTuple
和FieldNameTuple
,真正的模板插件
,有简单的解决方法:命名mixin 模板
,可消除
歧义.
在插件代码
中使用了静态导入和全限定名
,包括使用FieldTypeTuple
的本地符号而不是field.stringof
来尽量保持命名空间整洁
.
struct A { import arsd.color; Color a; }
AB ab;
import arsd.color;
ab.a = Color.white; ab.b = 2;
//接着
struct A { import arsd.color; Color a; }
struct B { int b; }
struct Color { static Color white() { return Color.init; } }
mixin CatStruct!("AB", A, B);
AB ab;
import arsd.color;
ab.a = Color.white; ab.b = 2;
对于与本地静态
导入一起使用的长格式FieldTypeTuple
,它始终指传入的实际类型
.间接地,当然,但也很明确.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现