Код: Выделить всё
template
struct ag_init {
T a, b;
};
< /code>
Создание этого приятно писать и довольно просто благодаря назначенным инициализаторам: < /p>
ag_init a1{.a = 1, .b = 2};
< /code>
Представьте себе, что у меня есть несколько пользовательских типов, которые могут неявно преобразовать друг друга: < /p>
struct float_like {
float i;
};
struct double_like {
double d;
double_like() = default;
double_like(double) {}
double_like(float_like) {}
};
< /code>
Это распространено, например. GLM :: fVEC3
Код: Выделить всё
ag_init a1{.a = float_like{1}, .b = float_like{2}};
ag_init a2{.a = double_like{1}};
a2 = a1; // assignment
ag_init a4{a1}; // converting construction
< /code>
назначение легко: < /p>
struct ag_init {
...
template
requires (!std::is_same_v) // Prevents trashing of other automatically generated operators.
ag_init& operator=(ag_init other) {
return *this;
}
template
requires (!std::is_same_v)
ag_init(ag_init other) {}
< /code>
Я предоставил конструктор. Это:
a. Делает это не конструктивным по умолчанию.
b. Делает это не заполнять. Это означает, что мои красивые назначенные инициализаторы не могут работать. Лучшее, что я придумал, это что -то вроде: < /p>
// A helper for allowing designated initializers
template
struct ag_ag
{
T a, b;
};
template
struct ag_init {
T a, b;
ag_init() = default;
template
requires (!std::is_same_v)
ag_init& operator=(ag_init other) {
return *this;
}
template
requires (!std::is_same_v)
ag_init(ag_init other) {}
// A little syntactic suger, makes a copy though

ag_init(ag_ag i) : a{i.a}, b{i.b} {}
template
ag_init& operator=(ag_ag i) {
return *this;
}
};
< /code>
Это позволяет что -то закрыть: < /p>
ag_init a1 = ag_ag{.a = float_like{1}, .b = float_like{2}};
< /code>
Но есть что не нравится: < /p>
- Копии < /li>
Необходимость писать название специальной базовой инициализации. (Может быть, в случае, когда есть много членов для инициализации).
Подробнее здесь: https://stackoverflow.com/questions/793 ... -available