Пользовательские атрибуты (UDA) [перевод]

Пользовательские атрибуты (User-Defined Attributes, UDA) — это выражения времени компиляции, которые можно добавить к объявлению чего-либо. Затем эти атрибуты можно запрашивать, извлекать и изменять во время компиляции. Для них нет исполняемого компонента.

Пользовательский атрибут выглядит, например, так:

@(3) int a;

@("string", 7) int b;

enum Foo;
@Foo int c;

struct Bar
{
    int x;
}

@Bar(3) int d;

Если в области действия объявления есть несколько UDA, они объединяются:

@(1)
{
    @(2) int a;         // имеет UDA (1, 2)
    @("string") int b;  // имеет UDA (1, "string")
}

Пользовательские атрибуты могут быть извлечены в кортеж выражения с помощью __traits:

@('c') string s;
pragma(msg, __traits(getAttributes, s)); // выведет tuple('c')

Если для символа нет определенных пользователем атрибутов, возвращается пустой кортеж. Кортеж выражения можно превратить в управляемый кортеж:

enum EEE = 7;
@("hello") struct SSS { }
@(3) { @(4) @EEE @SSS int foo; }

alias TP = __traits(getAttributes, foo);

pragma(msg, TP); // выведет tuple(3, 4, 7, (SSS))
pragma(msg, TP[2]); // выведет 7

Конечно, для объявления можно использовать типы кортежей:

TP[3] a; // a объявлен как SSS

Атрибут имени типа не совпадает с атрибутом переменной:

pragma(msg, __traits(getAttributes, typeof(a))); // выведет tuple("hello")

Настоящая ценность UDA — это возможность создавать определяемые пользователем типы с конкретными значениями. Значения атрибутов базовых типов не масштабируются. Кортежами атрибутов можно управлять, как и любым другим кортежем, и их можно передать в качестве списка аргументов в шаблон.

Являются ли атрибуты значениями или типами, зависит от пользователя, и будут ли более поздние атрибуты накапливаться или переопределяться более ранними, также зависит от того, как пользователь их интерпретирует.

UDA нельзя привязать к параметрам шаблона.

Источник: User-Defined Attributes

Добавить комментарий