UDA opCall __traits

Этот код завершается ошибкой при втором тестировании модуля при вызове getA!B(). Ошибка: "нужно" это для "значение" типа "строка"

Вопрос в том. Как заставить getA всегда возвращать A, независимо от того, является ли UDA типом или opCall?

    static A opCall(T...)(T args) {
        A ret;
        ret.value = args[0];
        return ret;
    }

    string value;
}

@A struct B {
}

@A("hello") struct C {
}

A getA(T)() {
    foreach(it; __traits(getAttributes, T)) {
        if(is(typeof(it) == A)) {
            A ret;
            ret.value = it.value;
            return ret;
        }
    }

    assert(false);
}

unittest {
    A a = getA!C();
    assert(a.value == "hello");
}

unittest {
    A a = getA!B();
    assert(a.value == "");
}

1 ответ

Решение

Как вы знаете, черты оцениваются во время компиляции. Поэтому любой самоанализ значений, полученных с помощью __traits, должен выполняться статически. К счастью, D имеет " статическое условие if" для этого.

Если вы измените

if(is(typeof(it) == A)) {

в

static if (is(typeof(it) == A)) {

у вас не должно возникнуть проблем при компиляции кода is(typeof(it) == A можно оценить во время компиляции.

Другие вопросы по тегам