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!0与func!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!0与func!0().我错了吗?
你没错.这种行为是typeof的特例.我只是解释为什么会引入这种特例.
我猜测是在,分析语义期间重写u.func2!0为func2!0(u),所以它不会触发特例.
相同问题:
import your.library;
struct MyStruct {
U myFunc() { /* ... */ }
}
@(MyStruct.myFunc) whatever;
我准备转成自由函数.
浙公网安备 33010602011771号