定义templatised类的特征

时间:2011-12-22 15:49:53

标签: c++ typetraits

我理解如何创建类型特征然后专门针对特定类,但在我的情况下,我想专门研究类模板。下面的代码没有编译,但是想法是Traits for MyTemplatisedClass的特化应该适用于用户决定使用MyTemplatisedType的类型。

class Traits
{
public:
    static bool someProperty(void) { return false; }
};

template<typename Type>
class MyTemplatisedClass
{
};

template<typename Type>
template<>
class Traits< MyTemplatisedClass<Type> >
{
public:
    static bool someProperty(void) { return true; }
};

int main(int argc, char* argv[])
{
    std::cout << Traits< MyTemplatisedClass<float> >::someProperty() <<std::endl; //This should be true
    return 0;
}

这可能还是我要求太多了?根据编译器的第一个问题是

error C2989: 'Traits' : class template has already been declared as a non-class template    

哪个是正确的,但我该如何解决这个问题? 如果它有任何区别我不需要它可以用于非模板化的课程,只有模板化的课程就可以了。 编辑:实际上如果它适用于它会很好无论是模板还是非模板化的课程。

3 个答案:

答案 0 :(得分:2)

Traits需要成为模板以便专业化。

在专业化中删除空<>行:这不是嵌套在模板中的模板或其他东西。

template <typename Type> //can only specialize templates
class Traits
{
public:
    static bool someProperty(void) { return false; }
};

template<typename Type>
class MyTemplatisedClass
{
};

template<typename Type>
//template<>  //Too much here
class Traits< MyTemplatisedClass<Type> >
{
public:
    static bool someProperty(void) { return true; }
};

但是如果你的意思是任何模板的专业化,那么它就是:

template < template <class> class SomeTemplatizedType, class Type>
//         ^^^^^^^^^^^^^^^^^^^^^^
//         names a template, not type
class Traits< SomeTemplatizedType<Type> >;
//            ^^^^^^^^^^^^^^^^^^^   ^
//             template name        |
//                               argument

答案 1 :(得分:1)

初始类需要是“基本情况”,即模板化接受任何类型参数。然后你可以担心你想要调用的其他专业。

template<typename T> class Traits
{
public:
    static bool someProperty(void) { return false; }
};

template<typename Type>
class MyTemplatisedClass
{
};

template<typename Type> class Traits< MyTemplatisedClass<Type> >
{
public:
    static bool someProperty(void) { return true; }
};

为了在编译时计算中实际使用,你需要使它成为ICE-整数常量表达式。函数不能是constexpr,即使在编译时它的值是可知的。就目前而言,我不能做,例如,

template<typename T> std::enable_if<Traits<T>::value, sometype> somefunc();

答案 2 :(得分:1)

问题在于您已将Traits声明为类,而不是类模板。只需将template<typename>添加到Traits的定义中,然后从专业化中删除虚假的template<>,就可以了。

template<typename>             // <--- Add this
class Traits
{
public:
    static bool someProperty(void) { return false; }
};

template<typename Type>
class MyTemplatisedClass
{
};

template<typename Type>
// template<>                 // <--- Remove this
class Traits< MyTemplatisedClass<Type> >
{
public:
    static bool someProperty(void) { return true; }
};

int main(int argc, char* argv[])
{
    std::cout << Traits< MyTemplatisedClass<float> >::someProperty() <<std::endl; //This should be true
    return 0;
}