首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将模板函数重载转换为部分专用模板类静态方法?

如何将模板函数重载转换为部分专用模板类静态方法?
EN

Stack Overflow用户
提问于 2013-02-27 14:52:33
回答 3查看 285关注 0票数 1

我想根据类型特性专门处理几个函数,例如“字符、有符号整数、无符号整数、浮点、指针”;使用type_traits似乎就是这样做的,并且代码类似于以下内容:

代码语言:javascript
复制
#include <tr1/type_traits>
#include <iostream>

template<bool, typename _Tp = void>
struct enable_if 
{ };

template<typename _Tp>
struct enable_if<true, _Tp>
{
    typedef _Tp type;
};


template< typename T >
inline void
foo_impl( typename enable_if< std::tr1::is_integral< T >::value, T >::type const& )
{
    std::cout << "This is the function-overloaded integral implementation.\n";
}

template< typename T >
inline void
foo_impl( typename enable_if< std::tr1::is_floating_point< T >::value, T >::type const& )
{
    std::cout << "This is the function-overloaded floating-point implementation.\n";
}

template< typename T >
inline void
function_overloads_foo( T const& arg )
{
    foo_impl< T >( arg ); // vital to specify the template-type
}

void function_overloads_example()
{
    function_overloads_foo( int() );
    function_overloads_foo( float() );
}

除了在我的真实代码中,我还有barbaz等,还有foo

但是,我想将所有这些函数按质量分组到一个模板类中,作为static方法。怎么做才是最好的呢?以下是我天真而失败的使用标记、SFINAE和部分专门化的尝试:

代码语言:javascript
复制
struct IntegralTypeTag;
struct FloatingPointTypeTag;

template< typename T, typename U = void >
class Foo
{
};

template< typename T >
class Foo< T, typename enable_if< std::tr1::is_integral< T >::value, IntegralTypeTag >::type >
{
    static void foo( T const& )
    {
        std::cout << "This is the integral partial-specialization class implementation.\n";
    }
};

template< typename T >
class Foo< T, typename enable_if< std::tr1::is_floating_point< T >::value, FloatingPointTypeTag >::type >
{
    static void foo( T const& )
    {
        std::cout << "This is the floating-point partial-specialization class implementation.\n";
    }
};

template< typename T >
inline void
partial_specialization_class_foo( T const& arg )
{
    Foo< T >::foo( arg );
}

void partial_specialization_class_example()
{
    partial_specialization_class_foo( int() );
    partial_specialization_class_foo( float() );
}

注意:在我的实际代码中,我将使用barbaz等以及foo静态方法。

我是C++03。

顺便说一句,我是不是按常规方式做了模板化的功能重载?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-27 15:20:55

以下是一种方法:

代码语言:javascript
复制
#include <tr1/type_traits>
#include <iostream>

struct IntegralTypeTag;
struct FloatingPointTypeTag;

template <
  typename T,
  bool is_integral = std::tr1::is_integral<T>::value,
  bool is_floating_point = std::tr1::is_floating_point<T>::value
> struct TypeTag;

template <typename T>
struct TypeTag<T,true,false> {
  typedef IntegralTypeTag Type;
};

template <typename T>
struct TypeTag<T,false,true> {
  typedef FloatingPointTypeTag Type;
};

template <typename T,typename TypeTag = typename TypeTag<T>::Type> struct Foo;


template <typename T>
struct Foo<T,IntegralTypeTag> {
  static void foo( T const& )
  {
    std::cout << "This is the integral partial-specialization class implementation.\n";
  }
};

template <typename T>
struct Foo<T,FloatingPointTypeTag> {
  static void foo( T const& )
  {
    std::cout << "This is the floating-point partial-specialization class implementation.\n";
  }
};

template< typename T >
inline void
partial_specialization_class_foo( T const& arg )
{
      Foo< T >::foo( arg );
}

int main(int,char**)
{
  partial_specialization_class_foo(int());
  partial_specialization_class_foo(float());
  return 0;
}
票数 2
EN

Stack Overflow用户

发布于 2013-02-27 16:30:30

在观察了沃恩的正确答案后,我想进一步简化它。我能够删除标记和额外特性类的使用,从而产生以下结构:

代码语言:javascript
复制
template< typename T, typename U = T >
struct Foo
{
};

template< typename T >
struct Foo< T, typename enable_if< std::tr1::is_integral< T >::value, T >::type >
{
    static void foo( T const& )
    {
        std::cout << "This is the integral partial-specialization class implementation.\n";
    }
};

template< typename T >
struct Foo< T, typename enable_if< std::tr1::is_floating_point< T >::value, T >::type >
{
    static void foo( T const& )
    {
        std::cout << "This is the floating-point partial-specialization class implementation.\n";
    }
};

template< typename T >
inline void
partial_specialization_class_foo( T const& arg )
{
    Foo< T >::foo( arg );
}

void partial_specialization_class_example()
{
    partial_specialization_class_foo( int() );
    partial_specialization_class_foo( float() );
}

我认为这是通过向类提供两个模板类型参数来实现的,其中第二个参数是编译时条件参数:

  • 这默认为与第一个参数相同,因此调用方只关注第一个参数。
  • 只有与第一个模板param相同的部分专门化才能被匹配。
  • enable_if失败时,整个部分专门化不可与之匹配.

相对而言,我觉得理解起来不那么麻烦。

票数 2
EN

Stack Overflow用户

发布于 2013-02-27 15:18:44

IntegralTypeTagenable_if中会受到阻碍。Foo的第二个参数的缺省值是void,这与IntegralTypeTag不一样,因此Foo的专门化将无法匹配。

Ie,Foo< int, void > (这是您做Foo<int>时得到的)与Foo< int, IntegralTypeTag >不匹配,您的int专门化是(在enable_if逻辑之后)。

标记是type_traits类的结果,然后您可以使用它来简化其他type_traits类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15115109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档