数据成员的编译时多态性
Compile-Time Polymorphism for Data Members
在下面的代码中,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, T*, 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!
};
所以当what
是true
时,data_type
就会变成T*
,否则就会变成std::vector<T>
。
在这两种情况下,您都不需要int2type
类模板。只需将其从代码中删除即可。
如何:
// Generic
template <typename T, typename Arg>
struct datum_type_dispatch {};
// Specialization for Arg = int2type<true>
template <typename T>
struct datum_type_dispatch<T, int2type<true> >
{
typedef T* type;
};
// Specialization for Arg = int2type<false>
template <typename T>
struct datum_type_dispatch<T, int2type<false> >
{
typedef std::vector<T> type;
};
template <typename T>
class Foo
{
// ...
private:
// Get the datum type based on int2type<...>
typedef typename datum_type_dispatch<T, int2type<is_trivially_copyable<T>::value> >::type datum_type;
datum_type m_datum;
};
相关文章:
- 多态性和功能结合
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- C ++中的方法覆盖:是编译时还是运行时多态性?
- 运行时与编译时多态性:更好的可读性与编译时错误检查,更重要的是
- 使用数组对对象的编译时多态性是否可行?
- 如果在编译时间中创建虚拟表,那么为什么我们将其称为运行时间多态性
- 编译时多态性运行时多态性是这样的吗
- C++编译时模板多态性
- 使用枚举编译时多态性
- 避免编译时已知类型的模板冗长和动态多态性
- 为什么不能在编译时解决运行时多态性?
- 如何实现几个函数的编译时多态性
- 尝试使用多态性C++时发生编译错误
- C++编译时多态性
- 编译时与运行时多态性在c++中的优缺点
- 允许运行时和编译时多态性的灵活方式
- 数据成员的编译时多态性
- 编译时多态性解决方案
- CRTP和动态多态性编译错误
- c++中运行时和编译时多态性的区别