1

我有几个想要基于类型质量专门化的函数,例如“字符、有符号整数、无符号整数、浮点数、指针”;使用 type_traits 似乎是这样做的方法,并且具有类似于以下的代码:

#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() );
}

除了在我的真实代码中,我还有bar,baz等,以及foo.

但是,我想将所有这些功能按质量分组到一个模板类中作为static方法。这怎么做最好?这是我使用标签、SFINAE 和部分专业化的天真和失败的尝试:

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() );
}

注意:在我的真实代码中,我有bar,baz等,以及foo静态方法。

仅供参考,这是 C++03。

顺便说一句,我是否以传统方式进行模板化函数重载?

4

3 回答 3

2

这是一种方法:

#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;
}
于 2013-02-27T15:20:55.490 回答
2

在观察了沃恩的正确答案之后,我想进一步简化它。我能够删除标签和额外的特征类的使用来提出以下结构:

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() );
}

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

  • 这默认与第一个参数相同,因此调用者只关注第一个参数。
  • 只有具有与第一个模板参数相同的第二个模板参数的部分特化才能匹配。
  • 失败时enable_if,整个部分专业化无法匹配。

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

于 2013-02-27T16:30:30.750 回答
0

IntegralTypeTagenable_if碍事。的第二个参数的默认值Foovoid,与 的不同IntegralTypeTag,所以特化 的Foo会匹配失败。

即,Foo< int, void >(这是你做的时候得到的Foo<int>)不匹配Foo< int, IntegralTypeTag >,你想要的int专业化是(在enable_if逻辑之后)。

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

于 2013-02-27T15:18:44.047 回答