简体   繁体   English

定义模板类的特征

[英]Defining traits for templatised classes

I understand how to create type traits and then specialise for a particular class, but in my case I would like to specialise for a class template. 我了解如何创建类型特征,然后专门针对特定的类,但就我而言,我想专门针对类模板。 The code below does not compile, but the idea is that the specialisation of Traits for MyTemplatisedClass should work for which ever type the user decides to use with MyTemplatisedType. 下面的代码无法编译,但是其想法是MyTemplatisedType的特质应适用于用户决定与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;
}

Is this possible or am I asking too much? 这可能还是我要求太多? According to the compiler the first problem is 根据编译器的第一个问题是

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

Which is correct, but how do I fix this? 哪个是正确的,但是我该如何解决? If it makes any difference I don't need it to work for non-templatised classes, just templatised ones is fine. 如果有什么不同,我不需要它在非模板化的类中工作,那么只需使用模板化的类即可。 Edit: Actually it would be nice if it worked for both templatised and non-templatised classes. 编辑:实际上,如果它适用于模板化和非模板化类,那将很好。

Traits needs to be a template in order to be specialized. Traits必须是模板才能被专门化。

In the specialization drop the line with empty <> : this isn't a template nested within a template or something. 在专业化中,添加带有空<>的行:这不是嵌套在模板之内的模板。

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

But if you meant the specialization for any template with one type argument, then that would be: 但是,如果要对具有一个类型实参的任何模板进行专业化处理,则将是:

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

The initial class needs to be the "base case", that is, templated to accept any type argument. 初始类必须是“基本情况”,即,以模板形式接受任何类型参数。 Then you can worry about what other specializations you'd like to invoke. 然后,您可以担心要调用其他哪些专业。

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

In order to actually use this in compile-time computation, you will need to make it an ICE- integral constant expression. 为了在编译时计算中实际使用它,您将需要使其成为ICE积分常数表达式。 A function cannot be constexpr even if, trivially, it's value is knowable at compile-time. 一个函数即使在编译时就可以知道它的值,也不能是constexpr As it stands, I cannot do, for example, 就目前而言,我不能这样做,

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

The problem is that you've declared Traits as a class, not a class template. 问题是您已将Traits声明为类,而不是类模板。 Just add template<typename> to the definition of Traits , and remove the spurious template<> from the specialisation and it should be fine. 只需将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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM