Функция и делегат литералов в D - PullRequest
7 голосов
/ 22 июня 2011

Чтение 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

UPDATE

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!!!!!

Miracle. Кажется, D2 еще не готов к использованию.

Ответы [ 2 ]

5 голосов
/ 22 июня 2011

«f» является переменной. is выражение сравнивает types . Это должно работать:

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

Если вы хотите создать функцию вместо делегата, вы можете использовать синтаксис литерала функции:

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

Если синтаксис литерала функции не используется, предполагается, что литерал является делегатом ( Выражения, смотрите в разделе «Литералы функций» . Это имеет смысл, поскольку D не должен изменять тип в зависимости от того, Тело литерала нуждается в кадре стека (это было бы очень плохо). EDIT: TDPL действительно указывает, что компилятор будет выводить функцию вместо делегата, если это возможно, независимо от ключевого слова "function". Это выглядит как плохой Идея для меня, так что это может быть что-то, что было отброшено.

Что касается того, почему функция is (f ==) не работает, это выглядит как регрессия.

4 голосов
/ 22 июня 2011

Вы можете найти isFunctionPointer и isDelegate полезными.

Обновление:

См. Это взято из 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));
}
...