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

前端之家收集整理的这篇文章主要介绍了c – 数据成员的编译时多态性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在下面的代码中,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类模板.只需从代码删除它即可.没有它,您可以编写更清晰的代码.

猜你在找的C&C++相关文章