Обеспечить преобразование между типами при сохранении специальных инициализаторов доступнымиC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Обеспечить преобразование между типами при сохранении специальных инициализаторов доступными

Сообщение Anonymous »

Представьте, что у меня есть какая -то структура, подобная следующей: < /p>

Код: Выделить всё

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 
может неявно преобразовать в GLM :: dVEC3 . Я хочу, чтобы моя структура унаследовала эту хорошую способность преобразования. Aka Я хочу иметь возможность сделать это: < /p>

Код: Выделить всё

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;
}
Теперь a2 = a1 работает, как и ожидалось. Но если я сделаю: < /p>
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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»