在下面的代码中,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>,如所希望的那样.