加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 数据成员的编译时多态性

发布时间:2020-12-16 04:57:11 所属栏目:百科 来源:网络整理
导读:在下面的代码中,initialize()说明了一个基于编译时多态的方法.编译的initialize()版本取决于int2type true和int2type false,对于给定的模板参数T,其中只有一个为真. 它恰好发生在数据成员T * m_datum;将适用于int2type true和int2type false. 现在,我想更改i
在下面的代码中,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>,如所希望的那样.

在任何一种情况下,您都不需要int2type类模板.只需从代码中删除它即可.没有它,您可以编写更清晰的代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读