The following initialize() code shows a method based on compile-time polymorphism. The compiled version of initialize() depends on int2type<true> and int2type<false> , only one of which will be true for the given template parameter T
It so happened that the data element T* m_datum; will work for both int2type<true> and int2type<false> .
Now I want to change the version of int2type<false> to std::vector<T> m_datum; , so my question is: how do I change my code so that the m_datum data member is polymorphic to int2type<> ?
Note: please ignore the code justification below - instead, I would like to focus on the mechanics of achieving compile time polymorphism for data members.
#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 solution based on Nawaz recommendations
#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; }
kfmfe04
source share