首页 > 解决方案 > 如何在 consteval 的编译时初始化可变数量的模板

问题描述

predef_ts() 在编译时通过遍历 variant_typesize<>() 返回模板 Ts 类型参数的对象表示(在变体中时)的大小数组,它为每个迭代器创建一个单独的模板实例化。

上线:s_arr[i] = variant_typesize<it, Ts...>(); ,模板的实例化是使用它在以下行声明的迭代器创建的:const std::size_t it = i。当它的值为 1 或 2 等 const 右值时,一切都按预期工作,但如果将其设置为任何非 const 值,则会引发以下错误。

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

由于这一切都需要在编译时发生,我显然不能 const_cast 或完全破坏类型安全。我似乎得到的印象是,如果调用者函数修改了任何模板类型,则无法从另一个 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;                                                     
};

非常感谢所有帮助。

标签: c++templates

解决方案


推荐阅读