Как инициализировать различное количество шаблонов во время компиляции в consteval

#c #templates

Вопрос:

функция predef_ts() возвращает массив размеров представления объекта(в варианте) параметров типа Ts шаблона во время компиляции путем итерации с помощью функции variant_typesize<>(), которая создает отдельный экземпляр шаблона для каждого итератора.

в строке: s_arr[i] = variant_typesize<it, Ts…>();<it, Ts…> создается экземпляр шаблона с итератором, объявленным в строке: const std::size_t it = i. Когда его значение является постоянным значением, таким как 1 или 2, все работает как ожидалось, но если оно установлено в любое значение, не являющееся постоянным, возникает следующая ошибка.

 error: no matching function for call to ‘variant_typesize< ... >()
 

Поскольку все это должно происходить во время компиляции, я, очевидно, не могу полностью переадресовывать или нарушать безопасность типов. У меня, кажется, складывается впечатление, что шаблоны consteval не могут быть созданы из другой функции consteval, если какой-либо из типов шаблонов изменен вызывающей функцией.

Несмотря на это, кажется, что это должно быть возможно, поскольку количество параметров шаблона известно при инициализации шаблонов variant_typesize<> (). Я чувствую, что мне здесь чего-то не хватает, хотя, поскольку это кажется обычным делом. Код для этого приведен ниже.

 std::size_t is;
template <std::size_t it, typename... Ts>
[[nodiscard]] std::size_t
consteval variant_typesize()
{
    assert(it < sizeof...(Ts));                         
    std::variant<Ts...> table[] = { Ts{ }... };         
    return sizeof( std::get<it, Ts...>(table[it]) );    
}

template <typename... Ts>
consteval std::array<std::size_t, std::variant_size_v< std::variant<Ts...> > > predef_ts()
{
    typedef std::variant<Ts...> ts_variant;                           
    std::array<std::size_t, std::variant_size_v<ts_variant>> s_arr{}; 
    for(uint16_t i=0; i < s_arr.size(); i  )
    {
        const std::size_t it = i;     // if this value is a const rvalue like 1, everything works fine
        s_arr[i] = variant_typesize<it, Ts...>(); 
    }                   
    return s_arr;                                                     
};
 

Мы очень признательны за любую помощь.

Комментарии:

1. Я не уверен, почему variant это имеет значение. variant_typesize просто возвращает размер типа it th Ts , не так ли? Какой смысл упаковывать типы в варианты только для того, чтобы извлечь тип обратно, просто чтобы взять его sizeof ? Какой смысл на самом деле создавать экземпляр table массива? Размер типа не зависит от того, как построен объект этого типа.

2. Чем это predef_ts отличается от template <typename... Ts> constexpr auto predef_ts() { return std::array<std::size_t, sizeof...(Ts)>{sizeof(Ts)...}; } ? Должно быть, я упускаю что-то очевидное.

3. @IgorTandetnik Да, это правильно, я не был уверен, изменится ли порядок, если вариант не будет использован, но это работает идеально. Спасибо.