我想根据类型质量专门设置几个函数,例如“字符,有符号整数,无符号整数,浮点数,指针”;使用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。
顺便说一句,我是否以常规方式进行模板化函数重载?
答案 0 :(得分: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;
}
答案 1 :(得分:2)
在观察了Vaughn的正确答案之后,我想更多地简化它。我能够删除使用标签和额外特征类来提出以下结构:
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
失败时,整个部分专业化无法与之匹配。相对而言,我觉得理解起来不那么麻烦。
答案 2 :(得分:0)
IntegralTypeTag
中的 enable_if
会妨碍您。 Foo
的第二个参数的默认值为void
,与IntegralTypeTag
不同,因此Foo
的特化将无法匹配。
即,Foo< int, void >
(这是您Foo<int>
时得到的)与您Foo< int, IntegralTypeTag >
专业化所需的int
不匹配({{1}之后逻辑)。
标记是enable_if
类的结果,您可以使用它来简化其他type_traits
类。