生成了数组编译时

Array compile-time generated?

本文关键字:编译 数组      更新时间:2023-10-16

在这个答案中(并非严格需要阅读整个问题+答案),一些代码生成一个编译时数组,如:

template<unsigned...Is,class Tuple>
unsigned index_of(indexes<Is...>,void const* p, Tuple const&t){
  void const* r[]={ nullptr, &std::get<Is>(t)... }; // <-- this is the array I'm referring to
  auto it = std::find( std::begin(r), std::end(r), p );
  if (it==std::end(r))
    return -1;
  else
    return (it-std::begin(r))-1;
}

我的问题是:这个数组是否完全是用元组中每个元素的地址在编译时生成的?这就是编译时的优势吗?或者数组运行时是生成的(在这种情况下,编译时的优势在哪里?)


重新表述:为什么这里需要复杂的模板化代码,而不是简单的运行时函数,该函数用for循环迭代元组的所有元素并比较指针?这一切有什么收获??关于数组创建的问题?我真的没有看到,我不敢相信所有的工作都是徒劳的,或者只是吹嘘"我可以用模板把东西搞砸,看看"

否,因为元组地址在编译时是未知的。编译时唯一已知的是数组的大小,因为它是从元组的大小中提取的(通过包扩展)。

这是一个奇怪的算法,它只通过void*进行类型擦除,以便能够将元组元素存储在数组上,然后通过标准算法对它们进行处理。

这更有意义(指数技巧被认为更清晰):

template<typename Tuple , typename T>
bool find_in_tuple( const Tuple& t , const T& e )
{
    bool result[] = { (std::get<Indices>( t ) == e)... };
    return std::any_of(std::begin(result) , std::end(result) , [](bool b){ return b; } );
}

下面是一个运行示例。

对于index_of特性,您可以在执行any_of()时向闭包添加计数器,或者执行更复杂的操作,如

template<typename Tuple , typename T>
std::index_of index_of( const Tuple& t , const T& e )
{
    std::size_t index = 0;
    std::tuple<bool,std::size_t> result[] = { std::make_tuple(Indices,std::get<Indices>( t ) == e)... };
    bool exists = std::any_of(std::begin(result) , std::end(result) , [&](const std::pair<std::size_t,bool>& p){ index = p.first; return p.second; } );
    if(exists)
        return index;
    else
        throw std::bad_argument{};
}