C++ 模板元魔术
我最近遇到了一种基于数据类型“概念”的分派模式(我认为这是术语概念的正确用法,如果不是,属性??) 在我看来,它比我以前见过的类型要复杂一些,至少在优化之前,它引入了临时变量和函数调用。我的问题是(1)这一切真的得到了优化吗??(2) 这是执行这种基于类型的分派的“最佳”方式吗 我正在阅读的代码涉及迭代器类型,因此我将继续使用它作为模式的示例。下面的函数C++ 模板元魔术,c++,templates,C++,Templates,我最近遇到了一种基于数据类型“概念”的分派模式(我认为这是术语概念的正确用法,如果不是,属性??) 在我看来,它比我以前见过的类型要复杂一些,至少在优化之前,它引入了临时变量和函数调用。我的问题是(1)这一切真的得到了优化吗??(2) 这是执行这种基于类型的分派的“最佳”方式吗 我正在阅读的代码涉及迭代器类型,因此我将继续使用它作为模式的示例。下面的函数iter\u kind接受任何类型的变量,并返回特定“概念”类型的伪变量。类似于random\u access\u iterator\u kin
iter\u kind
接受任何类型的变量,并返回特定“概念”类型的伪变量。类似于random\u access\u iterator\u kind
,或者如果\u Iter
是非迭代器类型null\u iterator\u kind
template <typename _Iter>
INLINE_CALL typename iterator_traits<_Iter>::iter_kind iter_kind(_Iter&)
{
typename iterator_traits<_Iter>::iter_kind _ret;
return ( _ret );
}
不,这不是最好的办法。您可以在编译时选择正确的重载,例如:
template <typename _Iter, typename _Pred>
_Iter binary_search(_Iter head, _Iter tail, _Pred pred_less)
{
binary_search_impl(head, tail, pred_less,
std::iterator_traits<_Iter>::iterator_category());
}
模板
_国际热核实验堆二元搜索(国际热核实验堆头、国际热核实验堆尾、国际热核实验堆前、后)
{
二进制搜索(头、尾、无预测、,
std::iterator_traits::iterator_category();
}
更好的方法是在实际函数的签名中使用SFINAE,运行时开销为零:基本上,您可以在迭代器类别上使用
std::enable_if
,告诉编译器选择哪个重载。好吧,不,这不是最好的方法。您可以在编译时选择正确的重载,例如:
template <typename _Iter, typename _Pred>
_Iter binary_search(_Iter head, _Iter tail, _Pred pred_less)
{
binary_search_impl(head, tail, pred_less,
std::iterator_traits<_Iter>::iterator_category());
}
模板
_国际热核实验堆二元搜索(国际热核实验堆头、国际热核实验堆尾、国际热核实验堆前、后)
{
二进制搜索(头、尾、无预测、,
std::iterator_traits::iterator_category();
}
更好的方法是在实际函数的签名中使用SFINAE,运行时开销为零:基本上,您可以在迭代器类别上使用
std::enable_if
,告诉编译器选择哪个重载。是的,这些东西确实得到了优化。编译器是专门编写的,目的是在它完成后清除这些垃圾,因为这是一个常见的技巧。函数和重载是通过这种方式完成的,因为它比任何其他方式都简单得多。这是标准库实现中使用的常见技巧。是的,这些东西确实都得到了优化。编译器是专门编写的,目的是在它完成后清除这些垃圾,因为这是一个常见的技巧。函数和重载是通过这种方式完成的,因为它比任何其他方式都简单得多。这是标准库实现中常用的技巧。他在上面张贴的是标准库的内部工作。他在上面张贴的是标准库的内部工作。