不同类型的模板特化的最佳方式

时间:2015-08-28 11:55:34

标签: c++ templates c++11 template-specialization

在网上查看库,stackoverflow问题和文章时,结果表明C ++ 11中有两种主要方式可以为不同类型创建相同功能的模板特化(如果需要,则为部分):

具有SFINAE返回类型的

功能模板
#include <type_traits>

namespace detail
{    
    template <class T>
    typename std::enable_if<std::is_integral<T>::value, T>::type
    compute_thing(T n)
    {
        // do calculations and return something
    }

    template <class T>
    typename std::enable_if<std::is_floating_point<T>::value, T>::type
    compute_thing(T n)
    {
        // do calculations and return something
    }
}

template <class T>
T compute_thing(T n)
{
    return detail::compute_thing<T>(n);
}

具有SFINAE部分特化的结构/类模板

#include <type_traits>

namespace detail
{    
    template <class T, class Enable = void>
    struct compute_thing;

    template <class T>
    struct compute_thing<T, typename std::enable_if<std::is_integral<T>::value, T>::type>
    {
        static T call(T x)
        {
            // do calculations and return something
        }
    };

    template <class T>
    struct compute_thing<T, typename std::enable_if<std::is_floating_point<T>::value, T>::type>
    {
        static T call(T x)
        {
            // do calculations and return something
        }
    };
}

template <class T>
T compute_thing(T n)
{
    return detail::compute_thing<T>::call(n);
}

然而,目前尚不清楚:

  • 应该首选哪种风格?为什么?
  • 在可重用性,多功能性,编译时和运行时性能方面有哪些优点/缺点?

1 个答案:

答案 0 :(得分:1)

如果结果需要一些处理或返回非const值,我会使用这个解决方案,使用函数:

template <class T>
typename std::enable_if<std::is_integral<T>::value, T>::type compute_thing(T n)
{
    return some_integral_calc(n);
}

template <class T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type compute_thing(T n)
{
    return some_fp_calc(n);
}

但是如果我能让编译器完成获取我的const值的工作(例如通过constexpr。)我会尽可能使用特殊的结构。

https://en.wikipedia.org/wiki/Template_metaprogramming#Compile-time_class_generation