d转发元组到局部变量
原文
为什么params
元组变量在构造后
立即销毁?
为什么是check(-2)
在dtor(2)
后?
import std.stdio : writeln;
import core.lifetime : forward, move;
struct Foo{
int i;
this(int i){
this.i = i;
writeln("ctor(", i, "): ", cast(void*)&this);
}
~this(){
writeln("dtor(", i, "): ", cast(void*)&this);
i *= -1;
}
}
void seq(Args...)(auto ref Args args){
Args params = forward!args;//这里
writeln("初化");
alias foo = params[0];
writeln("check(", foo.i, "): ", cast(void*)&foo);
}
void main(){
writeln("Foo(1):");
{
auto foo = Foo(1);
writeln("check(", foo.i, "): ", cast(void*)&foo);
}
writeln("\nFoo(2):");
seq(Foo(2));
}
输出:
Foo(1):
ctor(1): 7FFEBCAF0538
check(1): 7FFEBCAF0538
dtor(1): 7FFEBCAF0538
Foo(2):
ctor(2): 7FFEBCAF0548
dtor(2): 7FFEBCAF04F0
params initialized
check(-2): 7FFEBCAF04F0
dtor(0): 7FFEBCAF0558
亚当:
不能转发
到局部变量
.局部变量将是元组的副本
.转发
仅在直接发送
到另一个函数
调用时才真正管用.
D中有很多东西
只适用于函数参数列表
而不是局部变量
.这是其中之一.
vit:
谢谢,为什么元组
类型的局部变量
在初化
后立即调用析构函数
?
import std.stdio : writeln;
import std.meta : AliasSeq;
struct Foo{
int i;
this(int i){
this.i = i;
writeln("ctor(", i, "): ", cast(void*)&this);
}
~this(){
writeln("dtor(", i, "): ", cast(void*)&this);
i *= -1;
}
}
void main(){
{
AliasSeq!(Foo, Foo) tup;
static foreach(alias x; tup)
writeln("check(", x.i, "): ", cast(void*)&x); //x析构了.
}
}
输出:
dtor(0): 7FFF30D76868
dtor(0): 7FFF30D76858
check(0): 7FFF30D76858 //悬挂?
check(0): 7FFF30D76868 //悬挂?
我不明白局部变量
的来源.如果想要一对Foo
对象,我会用std.typeconst.Tuple
.
否则我会使用AliasSeq
,按我理解它如下所示:
alias tup = AliasSeq!(Foo, Foo);
static foreach(Type; tup) {{
Type x;
writeln("check(", x.i, "): ", cast(void*)&x);
}}
AliasSeq!(Foo, Foo)
是一对类型,我单独为每种类型实例化一个对象
并在内部使用
它
我想这样:
import std.stdio : writeln;
import std.meta : AliasSeq, staticMap;
import core.memory : pureMalloc, pureFree;
import core.lifetime : emplace, forward;
void main()@safe{
auto rc1 = RcPtr!int.make(1); //ref counted pointer
long result = 0;
//apply can be @safe
apply!((ref int a, ref long b){
rc1 = null; //apply has copy of rc1, a is not dangling reference
result = a + b;
})(rc1, RcPtr!long.make(2));
assert(result == 3);
}
//@safe access to data of multiple ref counted objects:
public auto apply(alias fn, Args...)(scope auto ref Args args){
Args params = forward!args; //copy lvalue and move rvalue args
@property auto ref elm(alias param)()@trusted{
return param.get();
}
return fn(staticMap!(elm, params));
}
//simple implementation of ref counted pointer
struct RcPtr(T){
private Payload* payload;
private this(Payload* payload)@safe{
this.payload = payload;
}
//copy ctor
public this(ref typeof(this) rhs){
this.payload = rhs.payload;
if(payload)
payload.count += 1;
}
//make data
public static auto make(Args...)(auto ref Args args){
Payload* payload = ()@trusted{
return cast(Payload*)pureMalloc(Payload.sizeof);
}();
emplace(payload, forward!args);
return RcPtr(payload);
}
public ~this(){
this.opAssign(null);
}
//release payload
void opAssign(typeof(null) nil){
if(payload){
payload.count -= 1;
if(payload.count == 0){
destroy(*payload);
()@trusted{
pureFree(payload);
}();
payload = null;
}
}
}
//
ref T get()@system{
assert(payload);
return payload.data;
}
private struct Payload{
int count = 1;
T data;
this(Args...)(auto ref Args args){
data = T(forward!args);
}
}
}
按值取并复制
而不转发
:
import std.typecons : Tuple;
import std.meta : allSatisfy;
enum bool isRcPtr(T) = is(T == RcPtr!U, U);
//@safe访问多引用计数对象数据
public auto apply(alias fn, Args...)(Args args)if (allSatisfy!(isRcPtr, Args)) {
Tuple!Args params = args; // borrow all
@property auto ref elm(alias param)()@trusted{
return param.get();
}
return fn(staticMap!(elm, args));
// 静每一,每个元类型
}
或造按值获取并转发
给它的辅助函数
.
template apply(alias fn)
{
private auto impl(Args...)(Args args)
{
@property auto ref elm(alias param)()@trusted{
return param.get();
}
return fn(staticMap!(elm, args));
}
auto apply(Args...)(auto ref Args args)
if (allSatisfy!(isRcPtr, Args))
{
import core.lifetime : forward;
return impl(forward!args);
// impl 按值取- 复制按引用传递的RcPtrs
}//根本不必要.
}
只要按值
计算,根本不需要额外副本
.
import std.meta : allSatisfy;
enum bool isRcPtr(T) = is(T == RcPtr!U, U);
public auto apply(alias fn, Args...)(Args args)
if (allSatisfy!(isRcPtr, Args)) {
@property auto ref elm(alias param)()@trusted{
return param.get();
}
return fn(staticMap!(elm, args));
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现