c – 数据成员的编译时多态性
发布时间:2020-12-16 04:57:11 所属栏目:百科 来源:网络整理
导读:在下面的代码中,initialize()说明了一个基于编译时多态的方法.编译的initialize()版本取决于int2type true和int2type false,对于给定的模板参数T,其中只有一个为真. 它恰好发生在数据成员T * m_datum;将适用于int2type true和int2type false. 现在,我想更改i
在下面的代码中,initialize()说明了一个基于编译时多态的方法.编译的initialize()版本取决于int2type< true>和int2type< false>,对于给定的模板参数T,其中只有一个为真.
它恰好发生在数据成员T * m_datum;将适用于int2type< true>和int2type< false>. 现在,我想更改int2type< false>版本到std :: vector< T> m_datum;,所以我的问题是,我如何修改我的代码,以便数据成员m_datum在int2type<>?上是多态的? 注意:请忽略下面代码背后的基本原理 – 相反,我想重点关注为数据成员实现编译时多态的机制. #include <type_traits> #include <stdlib.h> using namespace std; template <bool n> struct int2type { enum { value = n }; }; template< typename T > struct is_trivially_copyable { static const bool value = std::is_standard_layout<T>::value; }; template<class T> class Foo { public: Foo( size_t n ) : m_nr( n ) { initialize( int2type<is_trivially_copyable<T>::value>() ); } ~Foo() { } private: void initialize( int2type<true> ) { m_datum = (T*) calloc( sizeof(T),m_nr ); } void initialize( int2type<false> ) { m_datum = new T[m_nr]; } private: size_t m_nr; T* m_datum; // ok for int2type<true> // vector<T> m_datum; // want to change to this for int2type<false> }; class Bar { public: Bar() { } virtual ~Bar() { } }; int main(int argc,char** argv) { Foo<int> foo_trivial( 5 ); Foo<Bar> foo_nontrivial( 10 ); return 0; } C 11解决方案,基于Nawaz的建议 #include <type_traits> #include <vector> #include <stdlib.h> using namespace std; template< typename T > struct is_trivially_copyable { static const bool value = std::is_standard_layout<T>::value; }; template<class T> class Foo { private: static const bool what = is_trivially_copyable<T>::value; typedef typename std::conditional<what,T*,std::vector<T>>::type type; public: Foo( size_t n ) : m_nr( n ) { initialize( m_datum ); } ~Foo() { } private: void initialize( T* dummy ) { m_datum = (T*) calloc( sizeof(T),m_nr ); } void initialize( std::vector<T>& dummy ) { m_datum.resize( m_nr ); } private: size_t m_nr; type m_datum; }; class Bar { public: Bar() { } virtual ~Bar() { } }; int main(int argc,char** argv) { Foo<int> foo_trivial( 5 ); Foo<Bar> foo_nontrivial( 10 ); return 0; } 解决方法
C 11解决方案
使用std::conditional作为: #include <type_traits> template<class T> class Foo { //some info we can use throughout the class static const bool what = is_trivially_copyable<T>::value; typedef typename std::conditional<what,std::vector<T>>::type data_type; //data members data_type m_data; //this is what you need! } C 03解决方案 您可以编写一个元函数,并将其部分特化如下: template<class T> class Foo { //primary template template<bool b,typename T> struct get { typedef T* type; }; //partial specialization template<typename T> struct get<false,T> { typedef std::vector<T> type; }; //some info we can use throughout the class static const bool what = is_trivially_copyable<T>::value; typedef typename get<what,T>::type data_type; //data members data_type m_data; //this is what you need! }; 因此,当这是真的时,data_type将变成T *,否则它将是std :: vector< T>,如所希望的那样. 在任何一种情况下,您都不需要int2type类模板.只需从代码中删除它即可.没有它,您可以编写更清晰的代码. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |