在this answer中(完全没有必要阅读整个问题+答案)一些代码产生一个编译时数组,如:
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;
}
我的问题是:该数组完全是使用元组的每个元素的地址生成的编译时间吗?这是编译时的优势吗?或者是数组运行时生成的(在这种情况下,编译时优势在哪里?)
重新说明:为什么复杂的模板化代码here完全是必需的,而不是简单的运行时函数,它在元组的所有元素上迭代for循环并比较指针?这一切的收益是什么?有关阵列创建的事情?我真的没有看到它,我无法相信所有的工作都是无所事事,或者只是为了吹嘘而且#34; 我可以搞乱模板,看看&#34;
答案 0 :(得分:1)
不,因为在编译时不知道元组地址。在编译时唯一知道的是数组的大小,因为它是从元组的大小中提取的(通过包扩展)。
这是一种奇怪的算法,只能通过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; } );
}
Here是一个正在运行的例子。
对于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{};
}