d的typeof问题3

直觉,是这是用户错误.使用UDA的人都要知道,不是像普通表达式那样求值UDA.
即,如果想提供更好的API,建议是接受(a):U的实例,或(b)返回U可调用,可如下编码:

import std.traits, std.meta;

enum isOrReturnsU(alias attr) = is(typeof(attr) == U) || is(typeof(attr()) == U);
alias getMyUDAs(alias sym) = Filter!(isOrReturnsU, getUDAs!sym);

或推广到任意判词:

alias filterUDAs(alias sym, alias pred) = Filter!(pred, getUDAs!sym);

大概是因为如果完全一样,则不能直接反省U.func!0的类型.最接近的是检查typeof(&U.func!0);,即,函数指针类型而不是函数自身类型.
我不确定当前行为是正确的决定,但确实存在权衡.

印象是,如果模板函数无运行时参数,则可不带括号调用模板函数,因此func!0func!0()等价.我错了吗?
如果考虑自由成员函数,为什么typeof(u.func!0)typeof(u.func2!0),这里不一样?
typeof(u.func2!0)这样,正确吗?

struct U
{
    ref U func(int i)() { return this; }
}
ref U func2(int i)(ref U u) { return u; }

void main()
{
    U u;
    pragma(msg, typeof(u.func!0));    // pure nothrow @nogc ref @safe U() return
    pragma(msg, typeof(u.func2!0));    // U
}

UDA可以是表达式或符号.以下是一些不是有效表达式的UDA符号示例:

import std.stdio;
struct S;
template t() {}

@S           // 类型
@(std.stdio) // 模块
@t           // 模板
int n;

这是UFCS,在构函数时,存在歧义.是(实际上U)u的命名空间中func命名的函数吗?或是用u调用func?D编译器选择前者.
但是,对func2,在u的命名空间中没有func2,所以唯一选择是实际调用.

func!0func!0().我错了吗?
你没错.这种行为是typeof特例.我只是解释为什么会引入这种特例.
我猜测是在,分析语义期间重写u.func2!0func2!0(u),所以它不会触发特例.
相同问题:

import your.library;

struct MyStruct {
    U myFunc() { /* ... */ }
}

@(MyStruct.myFunc) whatever;

我准备转成自由函数.

posted @   zjh6  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示