2011-12-22 55 views
2

我明白如何创建类型特征,然后专门针对特定类,但在我的情况下,我想专门为类模板。下面的代码不能编译,但是想法是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  

哪个是正确的,但我要如何解决这个问题? 如果它有什么区别,我不需要它为非模板类​​工作,只是模板化的类是好的。 编辑:事实上,如果它适用于模板化和非模板化的类,它会很好。

回答

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 
+0

谢谢你们,你们都给出了正确的答案,但我只能接受一个。我将与UncleBens一起提供额外的信息。 – PolyVox 2011-12-22 16:22:43

+0

@UncleBens:你能否提供这两种情况的例子。我不太了解区别是什么,或者通过使用一个参数专门化“任何”模板意味着什么。 – Sarien 2012-08-27 07:59:33

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

为了实际使用在编译时计算,你将需要使它冰整型常量表达式。一个函数不能是constexpr,即使在编译时它的值是可知的。既然这样,我不能这样做,例如,

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

谢谢你们,你们都给出了正确的答案,但我只能接受一个。我将与UncleBens一起提供额外的信息。 – PolyVox 2011-12-22 16:22:53

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

谢谢你们,你们都给出了正确的答案,但我只能接受一个。我将与UncleBens一起提供额外的信息。 – PolyVox 2011-12-22 16:23:11