D中的函数和委托文字

时间:2011-06-21 20:58:03

标签: type-inference d

阅读有关函数和委托文字的TDPL(5.6.1)

auto f = (int i) {}; 
assert(is(f == function));

我有一个断言失败。这个断言是否正确?

我尝试了以下内容:

int z = 5;
auto f = (int i) { return i < 5; };
auto d = (int i) { return i < z; };
assert(is(typeof(f) == typeof(d)));

断言在那里有效。实际上f是委托,即使它不需要帧指针来访问局部变量也不是函数。这是一个错误吗?

另外,我不明白assert(is(f == function));应该如何运作。

我尝试了assert(is(f == delegate));,但也失败了。怎么了?

我使用DMD32 D Compiler v2.053

更新

auto f = (int i) {};
assert(is(typeof(f) == delegate))

工作正确,虽然没有理由成为代表

但是

auto f = function (int i) {};
assert(is(typeof(f) == void function(int))); // correct
assert(is(typeof(f) == function));           // failed!!!!!

奇迹。似乎D2尚未准备好用于生产。

2 个答案:

答案 0 :(得分:5)

“f”是一个变量。 表达式比较类型。这应该有效:

assert(is(typeof(f) == delegate));

如果要创建函数而不是委托,可以使用函数文字语法:

auto f = function (int i) { ... };
assert(is(typeof(f) == function));    // should be true

如果不使用函数文字语法,则假定文字是委托(Expressions, look under "Function Literals"。这是有道理的,因为D不应该根据文字的主体是否需要堆栈框架来更改类型(编辑:TDPL确实指定编译器会推断一个函数而不是一个委托,如果可以的话,无论“function”关键字如何。这对我来说似乎是一个糟糕的主意,所以这可能是某种东西已被删除。

至于为什么(f ==函数)不起作用,这看起来像一个回归。

答案 1 :(得分:4)

您可能会发现isFunctionPointerisDelegate有帮助。

更新

请参阅此摘录,摘自traits.d

template isSomeFunction(/+@@@BUG4217@@@+/T...)
    if (/+@@@BUG4333@@@+/staticLength!(T) == 1)
{
    enum bool isSomeFunction = isSomeFunction_bug4333!(T).isSomeFunction;
}
private template isSomeFunction_bug4333(T...)
{
    /+@@@BUG4333@@@+/enum dummy__ = T.length;
    static if (is(typeof(& T[0]) U : U*) && is(U == function))
        // T is a function symbol.
        enum bool isSomeFunction = true;
    else static if (is(T[0] W) || is(typeof(T[0]) W))
            // T is an expression or a type.  Take the type of it and examine.
        static if (is(W F : F*) && is(F == function))
            enum bool isSomeFunction = true; // function pointer
        else enum bool isSomeFunction = is(W == function) || is(W == delegate);
    else enum bool isSomeFunction = false;
}

我认为这可能会解释一些事情。

换句话说:

void main()
{
    static if (is(typeof(&main) T : T*))  static assert( is(T == function));
    static if (is(typeof(&main) U))       static assert(!is(U == function));
}