Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对自定义函数的理解_C++_Templates_User Defined Functions - Fatal编程技术网

C++ 对自定义函数的理解

C++ 对自定义函数的理解,c++,templates,user-defined-functions,C++,Templates,User Defined Functions,创建一个位字段的UserArray,其声明如下:数组占用的大小将小于普通数组。假设我们需要一个包含20个标志(TRUE/FALSE)的数组。bool标志[20]将占用20字节的内存,而UserArray将占用4字节的内存 使用类模板创建用户数组 使用逐位运算符打包阵列 还应实施平等操作 template<class T,int W,int L,int H>//i have used template<class T>

创建一个位字段的UserArray,其声明如下:数组占用的大小将小于普通数组。假设我们需要一个包含20个标志(TRUE/FALSE)的数组。
bool标志[20]
将占用20字节的内存,而
UserArray
将占用4字节的内存

  • 使用类模板创建用户数组
  • 使用逐位运算符打包阵列
  • 还应实施平等操作

    template<class T,int W,int L,int H>//i have used template<class T> 
                                       //but never used such way
    class UserArray{ 
            //....                 
    };        
    typedef UserArray<bool,4,0,20> MyType;
    
    template//我用过这个模板
    //但从未用过这种方式
    类UserArray{
    //....                 
    };        
    typedef UserArray MyType;
    
其中:

  • T=数组元素的类型
  • W=数组元素的宽度,0
  • L=数组索引的下限(最好为零)
  • H=数组索引的上限
主程序:

int main() {
      MyType Display;  //typedef UserArray<T,W,L,H> MyType; defined above

      Display[0] = FALSE; //need to understand that how can we write this?
      Display[1] = TRUE; //need to understand that how can we write this?

      //assert(Display[0]);//commented once, need to understand above code first
      //assert(Display[1]);//commented once..
      //cout << “Size of the Display” << sizeof(Display);//commented once..
}
intmain(){
MyType显示;//typedef UserArray MyType;已在上面定义
Display[0]=FALSE;//需要了解我们如何编写这个?
Display[1]=TRUE;//需要了解如何编写此代码?
//assert(Display[0]);//注释一次,需要先理解上面的代码
//断言(显示[1]);//注释一次。。

//cout
W
L
H
是非类型模板参数。您可以使用常量值实例化模板(在编译时),例如:

template <int N>
class MyArray
{
public:
    float data[N];

    void print() { std::cout << "MyArray of size " << N << std::endl; }
};

MyArray<7> foo;
MyArray<8> bar;

foo.print();  // "MyArray of size 7"
bar.print();  // "MyArray of size 8"
模板
类MyArray
{
公众:
浮点数据[N];

void print(){std::cout
W
L
H
是非类型模板参数。您可以使用常量值实例化模板(在编译时),例如:

template <int N>
class MyArray
{
public:
    float data[N];

    void print() { std::cout << "MyArray of size " << N << std::endl; }
};

MyArray<7> foo;
MyArray<8> bar;

foo.print();  // "MyArray of size 7"
bar.print();  // "MyArray of size 8"
模板
类MyArray
{
公众:
浮点数据[N];

void print(){std::cout这并不简单,特别是因为可以使用可变的位宽度

有一个常量
字符位
,它是一个字节中的位数。通常是8,但可以大于8(但不能小于8)

我建议每个字节的元素数为
CHAR\u-BIT/W
。例如,如果宽度为
3
CHAR\u-BIT
8
,这可能会浪费一些位,但这已经够复杂了

然后,您需要定义
运算符[]
来访问元素,并且可能需要进行一些修改来完成此操作。对于
运算符[]的非常量版本
,当一个字节中有多个元素时,可能必须返回某种代理对象,并重写其
运算符=
,以便将其写回数组中的相应位置


不过,这是一个很好的练习来解决这个问题。

这并不简单,特别是当您可以使用可变的位宽度时

有一个常量
字符位
,它是一个字节中的位数。通常是8,但可以大于8(但不能小于8)

我建议每个字节的元素数为
CHAR\u-BIT/W
。例如,如果宽度为
3
CHAR\u-BIT
8
,这可能会浪费一些位,但这已经够复杂了

然后,您需要定义
运算符[]
来访问元素,并且可能需要进行一些修改来完成此操作。对于
运算符[]的非常量版本
,当一个字节中有多个元素时,可能必须返回某种代理对象,并重写其
运算符=
,以便将其写回数组中的相应位置


不过,弄清楚这一点是一个很好的练习。

这里有一些代码实现了您所要求的功能,但下限固定为0。它还显示了运算符地址的一个罕见用例。如果您愿意,您可以更进一步,使此容器与STL算法兼容

#include <iostream>
#include <limits.h>
#include <stddef.h>

template<class T, size_t WIDTH, size_t SIZE>
class UserArray;

template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy;

template<class T, size_t WIDTH, size_t SIZE>
class UserArrayAddressProxy
{
public:
  typedef UserArray<T, WIDTH, SIZE> array_type;
  typedef UserArrayProxy<T, WIDTH, SIZE> proxy_type;
  typedef UserArrayAddressProxy<T, WIDTH, SIZE> this_type;

  UserArrayAddressProxy(array_type& a_, size_t i_) : a(a_), i(i_) {}
  UserArrayAddressProxy(const this_type& x) : a(x.a), i(x.i) {}

  proxy_type operator*() { return proxy_type(a, i); }

  this_type& operator+=(size_t n) { i += n; return *this; }
  this_type& operator-=(size_t n) { i -= n; return *this; }

  this_type& operator++() { ++i; return *this; }
  this_type& operator--() { --i; return *this; }

  this_type operator++(int) { this_type x = *this; ++i; return x; }
  this_type operator--(int) { this_type x = *this; --i; return x; }

  this_type operator+(size_t n) const { this_type x = *this; x += n; return x; }
  this_type operator-(size_t n) const { this_type x = *this; x -= n; return x; }

  bool operator==(const this_type& x) { return (&a == &x.a) && (i == x.i); }
  bool operator!=(const this_type& x) { return !(*this == x); }
private:
  array_type& a;
  size_t i;
};


template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy
{
public:
  static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
  static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
  static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
  static const T MASK = (1 << WIDTH) - 1;

  typedef UserArray<T, WIDTH, SIZE> array_type;
  typedef UserArrayProxy<T, WIDTH, SIZE> this_type;
  typedef UserArrayAddressProxy<T, WIDTH, SIZE> address_proxy_type;

  UserArrayProxy(array_type& a_, int i_) : a(a_), i(i_) {}

  this_type& operator=(T x)
  {
    a.write(i, x);
    return *this;
  }

  address_proxy_type operator&() { return address_proxy_type(a, i); }

  operator T()
  {
    return a.get(i);
  }
private:
  array_type& a;
  size_t i;
};

template<class T, size_t WIDTH, size_t SIZE>
class UserArray
{
public:
  typedef UserArrayAddressProxy<T, WIDTH, SIZE> ptr_t;

  static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
  static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
  static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
  static const T MASK = (1 << WIDTH) - 1;

  T operator[](size_t i) const
  {
    return get(i);
  }

  UserArrayProxy<T, WIDTH, SIZE> operator[](size_t i)
  {
    return UserArrayProxy<T, WIDTH, SIZE>(*this, i);
  }

  friend class UserArrayProxy<T, WIDTH, SIZE>;
private:
  void write(size_t i, T x)
  {
    T& element = data[i / ELEMENTS_PER_T];
    int offset = (i % ELEMENTS_PER_T) * WIDTH;
    x &= MASK;
    element &= ~(MASK << offset);
    element |= x << offset;
  }

  T get(size_t i)
  {
    return (data[i / ELEMENTS_PER_T] >> ((i % ELEMENTS_PER_T) * WIDTH)) & MASK;
  }
  T data[NUMBER_OF_TS];
};

int main()
{
  typedef UserArray<int, 6, 20> myarray_t;
  myarray_t a;
  std::cout << "Sizeof a in bytes: " << sizeof(a) << std::endl;
  for (size_t i = 0; i != 20; ++i) { a[i] = i; }
  for (size_t i = 0; i != 20; ++i) { std::cout << a[i] << std::endl; }
  std::cout << "We can even use address_of operator: " << std::endl;
  for (myarray_t::ptr_t e = &a[0]; e != &a[20]; ++e) { std::cout << *e << std::endl; }
}
#包括
#包括
#包括
模板
类用户数组;
模板
类UserArrayProxy;
模板
类UserArrayAddressProxy
{
公众:
typedef UserArray_类型;
typedef UserArrayProxy_类型;
typedef UserArrayAddressProxy此_类型;
UserArrayAddressProxy(数组类型和大小):a(a),i(i){
UserArrayAddressProxy(const this_type&x):a(x.a),i(x.i){
代理类型运算符*(){返回代理类型(a,i);}
this_type&运算符+=(size_t n){i+=n;返回*this;}
this_type&运算符-=(size_t n){i-=n;返回*this;}
this_type&operator++(){++i;返回*this;}
this_type&运算符--(){--i;返回*this;}
this_type运算符++(int){this_type x=*this;++i;返回x;}
this_type运算符--(int){this_type x=*this;--i;返回x;}
this_type操作符+(size_t n)const{this_type x=*this;x+=n;返回x;}
this_-type运算符-(size_t n)const{this_-type x=*this;x-=n;返回x;}
布尔运算符==(const this_type&x){return(&a==&x.a)&&(i==x.i)}
布尔运算符!=(const this_type&x){return!(*this==x);}
私人:
数组类型&a;
尺寸i;
};
模板
类UserArrayProxy
{
公众:
静态常量大小\u t位\u IN\u t=sizeof(t)*字符位;
静态常量大小\u t元素每\u t=位\u IN\u t/宽度;
静态常量大小\u t数量\u t=(大小-1)/每个元素\u t+1;

static const T MASK=(1这里有一些代码实现了您所要求的功能,但下限固定为0。它还显示了运算符地址_的一个罕见用例。如果您愿意,您可以更进一步,使此容器与STL算法兼容

#include <iostream>
#include <limits.h>
#include <stddef.h>

template<class T, size_t WIDTH, size_t SIZE>
class UserArray;

template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy;

template<class T, size_t WIDTH, size_t SIZE>
class UserArrayAddressProxy
{
public:
  typedef UserArray<T, WIDTH, SIZE> array_type;
  typedef UserArrayProxy<T, WIDTH, SIZE> proxy_type;
  typedef UserArrayAddressProxy<T, WIDTH, SIZE> this_type;

  UserArrayAddressProxy(array_type& a_, size_t i_) : a(a_), i(i_) {}
  UserArrayAddressProxy(const this_type& x) : a(x.a), i(x.i) {}

  proxy_type operator*() { return proxy_type(a, i); }

  this_type& operator+=(size_t n) { i += n; return *this; }
  this_type& operator-=(size_t n) { i -= n; return *this; }

  this_type& operator++() { ++i; return *this; }
  this_type& operator--() { --i; return *this; }

  this_type operator++(int) { this_type x = *this; ++i; return x; }
  this_type operator--(int) { this_type x = *this; --i; return x; }

  this_type operator+(size_t n) const { this_type x = *this; x += n; return x; }
  this_type operator-(size_t n) const { this_type x = *this; x -= n; return x; }

  bool operator==(const this_type& x) { return (&a == &x.a) && (i == x.i); }
  bool operator!=(const this_type& x) { return !(*this == x); }
private:
  array_type& a;
  size_t i;
};


template<class T, size_t WIDTH, size_t SIZE>
class UserArrayProxy
{
public:
  static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
  static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
  static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
  static const T MASK = (1 << WIDTH) - 1;

  typedef UserArray<T, WIDTH, SIZE> array_type;
  typedef UserArrayProxy<T, WIDTH, SIZE> this_type;
  typedef UserArrayAddressProxy<T, WIDTH, SIZE> address_proxy_type;

  UserArrayProxy(array_type& a_, int i_) : a(a_), i(i_) {}

  this_type& operator=(T x)
  {
    a.write(i, x);
    return *this;
  }

  address_proxy_type operator&() { return address_proxy_type(a, i); }

  operator T()
  {
    return a.get(i);
  }
private:
  array_type& a;
  size_t i;
};

template<class T, size_t WIDTH, size_t SIZE>
class UserArray
{
public:
  typedef UserArrayAddressProxy<T, WIDTH, SIZE> ptr_t;

  static const size_t BITS_IN_T = sizeof(T) * CHAR_BIT;
  static const size_t ELEMENTS_PER_T = BITS_IN_T / WIDTH;
  static const size_t NUMBER_OF_TS = (SIZE - 1) / ELEMENTS_PER_T + 1;
  static const T MASK = (1 << WIDTH) - 1;

  T operator[](size_t i) const
  {
    return get(i);
  }

  UserArrayProxy<T, WIDTH, SIZE> operator[](size_t i)
  {
    return UserArrayProxy<T, WIDTH, SIZE>(*this, i);
  }

  friend class UserArrayProxy<T, WIDTH, SIZE>;
private:
  void write(size_t i, T x)
  {
    T& element = data[i / ELEMENTS_PER_T];
    int offset = (i % ELEMENTS_PER_T) * WIDTH;
    x &= MASK;
    element &= ~(MASK << offset);
    element |= x << offset;
  }

  T get(size_t i)
  {
    return (data[i / ELEMENTS_PER_T] >> ((i % ELEMENTS_PER_T) * WIDTH)) & MASK;
  }
  T data[NUMBER_OF_TS];
};

int main()
{
  typedef UserArray<int, 6, 20> myarray_t;
  myarray_t a;
  std::cout << "Sizeof a in bytes: " << sizeof(a) << std::endl;
  for (size_t i = 0; i != 20; ++i) { a[i] = i; }
  for (size_t i = 0; i != 20; ++i) { std::cout << a[i] << std::endl; }
  std::cout << "We can even use address_of operator: " << std::endl;
  for (myarray_t::ptr_t e = &a[0]; e != &a[20]; ++e) { std::cout << *e << std::endl; }
}
#包括
#包括
#包括
模板
类用户数组;
模板
类UserArrayProxy;
模板
类UserArrayAddressProxy
{
公众:
typedef UserArray_类型;
typedef UserArrayProxy_类型;
typedef UserArrayAddressProxy此_类型;
UserArrayAddressProxy(数组类型和大小):a(a),i(i){
UserArrayAddressProxy(const this_type&x):a(x.a),i(x.i){
代理类型