如何在C ++中为非常量和本地数据伪造依赖类型?

时间:2012-11-23 19:32:19

标签: c++ templates types

下面是一些几乎可行的代码。我想要做的是创建内存池,在销毁时自动解压缩它们的内容(如果它仅适用于普通的旧数据,那就没关系),并且有一个编译时保证池必须总是比指向它内容的指针存活更长时间。在我尝试完成此操作时,我使指针具有池,它们指向它们类型的一部分。我的策略似乎应该可行,但C ++只允许常量或全局数据作为模板参数,这阻止了我编程的方式。例如,在下面的代码中,内存池必须是全局值。如何在C ++中为非常量和本地数据伪造依赖类型?

这是代码,以及一个显示如何使用它的简单示例。我为没有处理对齐问题而道歉,但这只是一个简单的概念证明。

#include <iostream>
#include <cstdlib>


class pool;

template<typename T, pool& H>
class reference;


class pool {
private:
 pool(const pool&);
 pool& operator=(const pool&);

 const pool* operator&() const;
 pool* operator&();


 size_t size; 
 void *storage;

 size_t tag;

public:
 pool() : size(0), storage(0) { }
 ~pool() { free(storage); }

template<typename, pool&> friend class reference;
template<typename T, pool& H> friend reference<T, H> allocate();
};


template<typename T, pool &H>
class reference {
private:
 reference();

 size_t index;

 reference(size_t _index) : index(_index) { }

public:
 friend class pool;

 void set(const T& rvalue) const {
  *((T*)&((char*)H.storage)[index]) = rvalue;
 }

 T operator*() const {
  return *((T*)&((char*)H.storage)[index]);
 }

 reference<T, H>& operator++() {
  index += sizeof(T);
  return *this;
 }

template<typename U, pool& I> friend reference<U, I> allocate();
};

// TODO: Add in alignment stuff
template<typename T, pool& H>
reference<T, H> allocate() {
 const size_t old_size = H.size;

 H.size += sizeof(T);
 H.storage = realloc(H.storage, H.size);

 return reference<T, H>(old_size);
}


template<pool& H>
reference<char, H> get_line() {
 const reference<char, H> start = allocate<char, H>();
 reference<char, H> end = start;

 char input;

 for (;;) {
  input = std::cin.get();

  if ('\n' == input) {
   break;
  }

  end.set(input);
  end = allocate<char, H>();
 }

 end.set('\0');

 return start; 
}

template<pool &H>
std::ostream& operator <<(std::ostream& out, reference<char, H> start) {
 for (; *start != '\0'; ++start)
  std::cout.put(*start);

 return out;
}


pool input_pool;

int main(int argc, char **argv) {

 std::cout << "What is your name?" << std::endl;

 const reference<char, input_pool> input_string = get_line<input_pool>();

 std::cout << "Hello " << input_string << "!" << std::endl;


 return 0;
}

1 个答案:

答案 0 :(得分:0)

我不确定这是否对您有所帮助,但以下编译:

class pool {};

template<pool& H>
class reference {
};

struct pools {
  static pool hopefullyStaysInCache;
  static pool hopefullyStaysInMemory;
  static pool canSwapOutToDisk;
};

main(){
  reference<pools::hopefullyStaysInMemory> y;
}

您可以确定不会太快删除这些池,因为它们永远不会被删除。可以删除池的存储空间,使其足够小,以至于您可能不介意保留它,并且可以在池中的最后一个引用被销毁时自动删除。