对用户定义函数的理解

发布于 2024-11-23 21:58:09 字数 1414 浏览 0 评论 0原文

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

  • 使用类 Template 创建用户数组。
  • 使用位运算符来打包数组。
  • 还应实行平等经营。

    template//我已经使用了template 
                                       //但从未使用过这种方式
    类用户数组{ 
            //....                 
    };        
    typedef UserArray;我的类型;
    

其中:

  • T = 数组元素的类型
  • W = 数组元素的宽度,0 < W< 8
  • 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..
}

我的疑问是这些参数(即 T,L,W & H 用于类 UserArray 中,我们如何将 UserArray 的实例编写为 Display[0] & Display[1] 它代表什么?

短&类似类型的简单示例对我来说很容易理解。

Create a UserArray of bit fields which can be declared as follows: The size occupied by our Array will be less then a normal array. Suppose we want an ARRAY of 20 FLAGs (TRUE/FALSE). A bool FLAG[20] will take 20 bytes of memory, while UserArray<bool,bool,0,20> will take 4 bytes of memory.

  • Use class Template to create user array.
  • Use Bit wise operators to pack the array.
  • Equality operation should also be implemented.

    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;
    

where:

  • T = type of an array element
  • W = width of an array element, 0 < W < 8
  • L = low bound of array index (preferably zero)
  • H = high bound of array index

A main program:

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..
}

My doubt is how those parameters i.e T,L,W & H are used in class UserArray and how can we write instance of UserArray as Display[0] & Display[1] what does it represent?

Short & simple example of similar type will be easy for me to understand.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诗笺 2024-11-30 21:58:09

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

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"

在上面的示例中,模板定义中出现 N 的任何地方,它将在编译时< /em> 由提供的常数决定。

请注意,就编译而言,MyArray<7>MyArray<8> 是完全不同的类型。

我不知道您的具体问题的解决方案是什么。但目前您的代码无法编译,因为您尚未为模板参数提供值。

W, L and H are non-type template parameters. You can instantiate a template (at compile-time) with constant values, e.g.:

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"

In the example above, everywhere that N appears in the template definition, it will be replaced at compile-time by the supplied constant.

Note that MyArray<7> and MyArray<8> are completely different types as far as the compile is concerned.

I have no idea what the solution to your specific problem is. But your code won't compile, currently, as you have not provided values for the template parameters.

羁客 2024-11-30 21:58:09

这并不简单,特别是因为您可以拥有可变的位宽度。

有一个常量 CHAR_BIT,它是一个字节中的位数。通常该值为 8,但也可能大于 8(但也不能小于 8)。

我建议每个字节的元素数量为CHAR_BIT / W。例如,如果宽度为 3CHAR_BIT8,这可能会浪费一些位,但这本身就足够复杂了。

然后,您需要定义 operator[] 来访问元素,并且可能需要做一些调整才能做到这一点。对于 operator[] 的非常量版本,当一个字节中有多个元素时,您可能必须返回某种代理对象,并使其具有 operator=< /code> 被覆盖,因此它写回到数组中的适当位置。

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

This is not simple, particularly as you can have variable bit widths.

<limits.h> has a constant CHAR_BIT, which is the number of bits in a byte. Usually this is 8, but it could be greater than 8 (not less though).

I suggest the number of elements per byte be CHAR_BIT / W. This might waste a few bits for example, if width is 3 and CHAR_BIT is 8, but this is complicated enough as is.

You'll then need to define operator[] to access the elements, and likely need to do some bit fiddling to do this. For the non-const version of operator[], you'll probably have to return some sort of proxy object when there are more than one elements in a byte, and have its operator= overridden so it writes back to the appropriate spot in the array.

It's a good exercise though to figure this one out though.

笑红尘 2024-11-30 21:58:09

下面是一些实现您所要求的代码,但下限固定为 0。它还显示了 address_of 运算符的罕见用例。如果您愿意,您可以更进一步,使该容器与 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; }
}

Here's some code that implements what you ask for, except the lower bound is fixed at 0. It also shows a rare use case for the address_of operator. You could take this further and make this container compatible with STL algorithms if you liked.

#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; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文