C ++ constexpr для генерации std :: vector - PullRequest
1 голос
/ 29 апреля 2019

Я хочу сгенерировать код для вектора на основе кода в лямбде.Я думаю, может быть, есть способ сделать это с constexpr, но я думаю, что это потребует чего-то особенно умного.Нечто подобное this кажется уместным, но способ, которым я хочу его генерировать, более непрозрачен, чем предусмотренный.Пример кода прояснит это:

Рассмотрим:

auto a = [&]() {
    if(!mem_retire_port->empty() && occupied) {
        auto addr = mem_retire_port->peek()->data.addr;
        if(addr == insns[idx]->ws.pc) {
            occupied = false;
            mem_retire_port->pop();
            insn_decode_port->push(new insn_decode_event_t(insns[idx]));
            idx = (idx + 1) % insns.size();
        }
    }
});

Я хочу сгенерировать std :: vector вида

std::vector<std::function<std::string()>> generated_vector = {mem_retire_port->get_name, insn_decode_port->get_name};

Эта информация очевиднодоступно для программиста, но мне было интересно, можно ли это определить программно во время компиляции.Может быть, constexpr на operator-> или что-то, чтобы определить, находится ли переменная в лямбде или нет.

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

1 Ответ

1 голос
/ 29 апреля 2019

Это невозможно, потому что std::vector разработан, чтобы не быть constexpr, и в настоящее время нет планов изменить это в какой-либо следующей версии стандарта C ++.

Теоретически, то, что вы пытаетесь сделать, понятно: std::vector по умолчанию использует динамически выделяемую память, но можно назначить ему распределитель, который вместо этого выделяет память из статической памяти; и при этом теоретически можно (условно) сделать весь класс constexpr; или хотя бы соответствующие детали.

Тем не менее. Это просто невозможно сейчас. Если вам нужен контейнер constexpr, размер которого варьируется в зависимости от условий компиляции, вам нужно что-то свернуть самостоятельно, поскольку std::vector просто не подходит для этой цели.

Возможно, проведите некоторое исследование, чтобы разобраться, если бы вы могли использовать std::array с шаблоном метапрограммирования черной магии, чтобы получить то, что вам нужно. Уже есть предложение для std::make_array, которое является одним из способов получить во время компиляции массив, размер которого программист не обязательно предвидит; поэтому посмотрите, можно ли применить подобное решение к вашей проблеме.

...