Использование шаблонного метапрограммирования (TMP) для создания однородно хранимых шаблонных конфигураторов - PullRequest
0 голосов
/ 01 апреля 2020

Извините за зверское название.

Сценарий состоит в том, что в моей программе есть система конфигурации, которая должна содержать значения всех типов. Эти значения (конфигураторы) должны храниться в однородном контейнере.

Например: (это псевдокод, я не уверен, как это будет выглядеть на самом деле)

configurant i(64);
configurant b(true);
configurant f(128.f);
configurant custom(Color(255, 255, 255));

vector<configurant> confs;
confs.emplace_back(i);
confs.emplace_back(b);
confs.emplace_back(f);
confs.emplace_back(custom);

// some form of accessing the vector with proper configurant type here:
// casting?

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

auto color = confs.at(3).rgb();

, вообще невозможно в C ++, но есть ли что-то, что я мог бы сделать с шаблонным метапрограммированием, чтобы попытаться максимально приблизиться к этому решению? (возможно, конфигураторы могли бы быть сопоставлены с их типом? но это не будет операция времени компиляции)

Я ищу создание системы, которая может быть однородно сохранена, немедленно доступна (не хранится в куче) и который оценивает достоверность операций во время компиляции.

Открыт для любых предложений.

И прежде чем комментарии поступят, я экспериментировал с std::any/std::any_cast, std::variant, шаблон посетителя и другие вещи такого рода. Я не собираюсь использовать ни одну из этих систем.

EDIT Чтобы избежать путаницы, есть N конфигураторов: это не группа статического размера конфигураторов. Пользователь этого интерфейса добавил бы больше конфигураций.

EDIT 2 Дополнительный пример желаемого использования

class foo {
configurant enabled;
configurant bar;
public:
    foo() {
        this->enabled = configurant(true);
        this->bar = configurant(5);
    }

    void body() {
        if(this->enabled) {
            std::cout << (this->bar < 100) << "\n";
        }
    }

    // It also needs to be kept in mind that these configurant classes
    // cannot be templated (directly, at least), since they need to be stored in 
    // a homogeneous container.
};

1 Ответ

1 голос
/ 01 апреля 2020

Из-за этого требования ", которое оценивает достоверность операций во время компиляции." , это означает, что ваш пример auto color = confs.at(3).rgb(); будет работать только с известным индексом 3 во время компиляции (почему бы не 2 или 4?).
Этот index не очень уместен / полезен в этой ситуации.

Может быть, вы просто подумаете структура, предоставляющая необходимые данные с правильным именем вместо индекса времени компиляции ?

struct Confs
{
  configurant<int> i;
  configurant<bool> b;
  configurant<float> f;
  configurant<Color> custom;
};

...
Confs confs{64, true, 128.f, Color(255, 255, 255)};
auto color = confs.custom.rgb();

Что-то подобное может опираться на индекс времени компиляции , но Я действительно не вижу преимущества по сравнению с именованным участником.

auto confs=std::make_tuple(64, true, 128.0f, Color{255, 255, 255});
auto color = std::get<3>(confs).rgb();
...