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