类型特征专业化

时间:2009-07-10 09:49:58

标签: c++ templates

template<typename T>
class vec3
{
public:
    typename T type_t;
    T x;
    T y;
    T z;
};

template<typename T>
struct numeric_type_traits_basic_c
{
    typedef T type_t;
    typedef T scalar_t;
};

template<typename T>
struct numeric_type_traits_vec3_c
{
    typedef T type_t;
    typedef typename T::type_t scalar_t;
};

typedef numeric_type_traits_basic_c<int> int_type_traits;
typedef numeric_type_traits_vec3_c< vec3<int> > vec3_int_type_traits;

这是标量和向量的类型特征,唯一的区别是向量的标量类型是其元素的类型。工作正常。

但我真的希望能够为这两个类使用相同的名称。

template<typename T>
struct numeric_type_traits_c
{
    typedef T type_t;
    typedef ????? scalar_t;
};

我知道如果该类明确专门用于我需要的每种类型,可以这样做:int,float,vec3,vec3 ...

这有很多重复......如何保持第一段代码的简单性,但同时具有相同的类名?

4 个答案:

答案 0 :(得分:5)

这是部分类模板专业化的语法:

template<typename T>
struct numeric_type_traits // basic template
{
    typedef T type_t;
    typedef T scalar_t;
};

template<typename T>
struct numeric_type_traits< vec3<T> > // partial specialisation for vec3's
{
    typedef vec3<T> type_t;
    typedef T scalar_t;
};

等等,例如:

template <typename T, typename T_Alloc>
struct numeric_type_traits< std::vector<T,T_Alloc> > // part. spec. for std::vector
{
    typedef std::vector<T,T_Alloc> type_t; // deal with custom allocators, too
    typedef T scalar_t;
};

答案 1 :(得分:0)

也许你应该用两种类型实例化你的模板?参见:

template<typename TYPE, typename SCALAR>
struct numeric_type_traits_c
{
   typedef TYPE type_t;
   typedef SCALAR scalar_t;
};

typedef numeric_type_traits_c<int,int> int_type_traits;
typedef numeric_type_traits_c<vec3<int>, vec3<int>::type_t> vec3_type_traits;

答案 2 :(得分:0)

template<typename T>
struct numeric_type_traits_c
{
        typedef T type_t;
        typedef T scalar_t;
};

template<typename T>
struct numeric_type_traits_c<vec3<T> >
{
        typedef vec3<T> type_t;
        typedef typename vec3<T>::type_t scalar_t;
};

是的,我确实在type_t中为vec3犯了一个错误!

答案 3 :(得分:0)

这里有一个有趣的评论在于将我们从动态多态性中获得的知识应用于'类型函数'多态性。

如果你比较这个函数f:

struct I { virtual double f()const = 0; }; // C++ version of 'an interface'
struct A : public I { virtual double f()const{ return 0; } };
struct B : public I { virtual double f()const{ return 1; } };
struct C { };

void f( const I& i ){ return I.f(); }

f( A() );
f( C() ); // compiler warning: wrong type provided.

使用此函数f:

// struct TI { typedef ??? iT; }; // no C++ version of a type-interface
struct TA { typedef int iT; };
struct TB { typedef double iT; };
struct TC { };

template< typename aTI > struct fT { typedef aTI::iT returnType; };

fT< TA >::returnType vA; 
ft< C  >::returnType vC; // compiler error: C has no iT member.

您看到唯一的区别是参数的表示法。第一个函数是“常规”多态函数。如果提供的参数不是正确的类型,编译器将警告我们。

fT是一个只能由编译器用来确定某种类型的函数。它需要一个类型作为参数。但是该语言没有类型约束的“概念”(但是 - 参见C ++ 0x中的概念)。所以我们需要亲自保证我们用于类型函数的类型“实现”正确的接口。

在concreto中,归结为将scalar_t类型添加到要与numeric_type_traits_c类型函数一起使用的任何类。