Войти
ПрограммированиеФорумОбщее

Крестопроблемы (4 стр)

Страницы: 1 2 3 4
#45
10:16, 25 янв 2023

Aroch
Почитай внимательней. Мы изучаем возможность инициализации членов туплы inplace, то есть без копирования или перемещения её членов. По аналогии с emplace в контейнерах. Здесь же ты явно создаешь экземпляры A, которые потом будут смещаться в туплу аа.

#46
(Правка: 11:10) 11:08, 25 янв 2023

Went
> Почитай внимательней. Мы изучаем возможность инициализации членов туплы
> inplace, то есть без копирования или перемещения её членов. По аналогии с
> emplace в контейнерах. Здесь же ты явно создаешь экземпляры A, которые потом
> будут смещаться в туплу аа.
ок, не вопрос:

std::tuple<A, A> aa(std::make_tuple<A, A>({1, 2}, {3}));

можешь и вовсе:

std::tuple<A, A> aa({1, 2}, {3});
#47
(Правка: 12:05) 12:04, 25 янв 2023

осталось как-то Immobile проинициализировать

#include <tuple>

struct Immobile
{
  Immobile() = default;
  Immobile(const Immobile&) = delete;
  Immobile(Immobile&&) = delete;
  Immobile& operator=(const Immobile&) = delete;
  Immobile& operator=(Immobile&&) = delete;
};

int main()
{
  std::tuple<Immobile, int> t(?, 10);
}

вернее не делать этого

#48
(Правка: 12:58) 12:57, 25 янв 2023

Идея - хранить поля как обычно, но в дополнение к ним дать одно из двух:
- мембер функцию field_refs, которая вернёт тьюпл из ссылок на все поля по очереди;
- статик функцию или константу на тьюпл из мембер-указателей на все поля по очереди.

Хотя сам тьюпл придётся всё-таки собирать вручную.

#49
13:07, 25 янв 2023

Aroch
> ок, не вопрос:
> std::tuple<A, A> aa(std::make_tuple<A, A>({1, 2}, {3}));
А разве здесь не будет копирования-перемещения экземпляров А внутри перемещаемой-копируемой туплы?

> можешь и вовсе:
> std::tuple<A, A> aa({1, 2}, {3});
Как я понимаю, мы сначала приводим {1, 2} к А (и {3} ко второй A), а потом вызываем обычный конструктор туплы с копированием-перемещением их вовнутрь оного.

#!
Да, вот тут как раз суть проблемы. Если конструктор не одного аргумента вызывать надо, то никак пока что не придумали.

#50
(Правка: 13:39) 13:34, 25 янв 2023

Went
> не одного аргумента вызывать надо, то никак пока что не придумали
придумали {}, но ты уже развенчал это выше

в целом проще всего написать функцию сериализации для структуры, как делали лет 20 назад, можно выборочно указать что сериализовать, а что нет

struct S
{
  Mem1 mem1;
  ...

  template <typename Arch> void serialize(Arch& ar)
  {
    ar & mem1;
    ...
  }
};

не знаю, разве протобуф не то же самое генерит? что-то я уже запутался зачем вообще кортежи всплыли

#51
(Правка: 16:24) 16:21, 25 янв 2023

Имбирная Ведьмочка
> - мембер функцию field_refs, которая вернёт тьюпл из ссылок на все поля по
> очереди;
Сработало на удивление гладко: https://godbolt.org/z/43MqGWTh4

Вариант с ссылками сразу на поля делать не стал - потому что в нём одну и ту же функцию придётся писать дважды, в конст- и нон-конст-варианте; тогда как поинтер-ту-мемберы - "полиморфны" относительно констности базового объекта.

tl;dr ключевого кода:

template<typename T, typename DT = decomposable_trait<T>>
std::string decomposable_to_string(T const& t) {
    std::string buffer;
    bool is_first = true;
    for_each_tuple_element(DT::fields, [&]<typename F>(F T::* field_mptr)
        {
            if (is_first)
                is_first = false;
            else
                buffer += " + ";
            buffer += (t.*field_mptr).to_string();
        });
    return buffer;
}

struct Foo {
    Bar<int> bi;
    Bar<float> bf;
    Bar<char> bc;
    Bar<Bar<bool>> bbb;
    Bar<bool> bb;

    std::string to_string() const {
        return decomposable_to_string(*this);
    }
};

template<>
struct decomposable_trait<Foo> {
    static constexpr auto fields =
        std::make_tuple(&Foo::bi, &Foo::bf, &Foo::bc, &Foo::bbb, &Foo::bb);
};
Страницы: 1 2 3 4
ПрограммированиеФорумОбщее