在以下代碼中,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的解決方案的基礎上,謝里夫的建議
#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;
}
它更傳統的使用'type'代替'data_type' – Abyx
@Abyx的:是的。我同意,並編輯。 :-) – Nawaz
+1:爲了解即將到來的標準的標準庫,以及通過避開OP的'int2type <>'繞道來鼓勵更乾淨的代碼。 –