C++ 模板元魔术

C++ 模板元魔术,c++,templates,C++,Templates,我最近遇到了一种基于数据类型“概念”的分派模式(我认为这是术语概念的正确用法,如果不是,属性??) 在我看来,它比我以前见过的类型要复杂一些,至少在优化之前,它引入了临时变量和函数调用。我的问题是(1)这一切真的得到了优化吗??(2) 这是执行这种基于类型的分派的“最佳”方式吗 我正在阅读的代码涉及迭代器类型,因此我将继续使用它作为模式的示例。下面的函数iter\u kind接受任何类型的变量,并返回特定“概念”类型的伪变量。类似于random\u access\u iterator\u kin

我最近遇到了一种基于数据类型“概念”的分派模式(我认为这是术语概念的正确用法,如果不是,属性??)

在我看来,它比我以前见过的类型要复杂一些,至少在优化之前,它引入了临时变量和函数调用。我的问题是(1)这一切真的得到了优化吗??(2) 这是执行这种基于类型的分派的“最佳”方式吗

我正在阅读的代码涉及迭代器类型,因此我将继续使用它作为模式的示例。下面的函数
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
,告诉编译器选择哪个重载。

是的,这些东西确实得到了优化。编译器是专门编写的,目的是在它完成后清除这些垃圾,因为这是一个常见的技巧。函数和重载是通过这种方式完成的,因为它比任何其他方式都简单得多。这是标准库实现中使用的常见技巧。

是的,这些东西确实都得到了优化。编译器是专门编写的,目的是在它完成后清除这些垃圾,因为这是一个常见的技巧。函数和重载是通过这种方式完成的,因为它比任何其他方式都简单得多。这是标准库实现中常用的技巧。

他在上面张贴的是标准库的内部工作。他在上面张贴的是标准库的内部工作。