题
我使用libgc,垃圾收集器C和C ++。 为了使STL容器垃圾收藏一个必须使用gc_allocator。
而不是写的
std::vector<MyType>
一个具有写
std::vector<MyType,gc_allocator<MyType> >
莫不是一种方法来定义类似
template<class T> typedef std::vector<T,gc_allocator<T> > gc_vector<T>;
我查了前一段时间,发现这是不可能的。但我可能是错误的或者附近可能有另一种方式。
以这种方式定义的地图是令人不愉快的特别
std::map<Key,Val>
变为
std::map<Key,Val, std::less<Key>, gc_allocator< std::pair<const Key, Val> > >
编辑:尝试使用宏我发现后,将下面的代码打破它:
#define gc_vector(T) std::vector<T, gc_allocator<T> >
typedef gc_vector( std::pair< int, float > ) MyVector;
模板化类型定义内的逗号被解释为宏参数隔板。
因此,似乎内类/结构是最好的解决方案。
下面是对如何将在C ++ 0X来完成的示例
// standard vector using my allocator
template<class T>
using gc_vector = std::vector<T, gc_allocator<T> >;
// allocates elements using My_alloc
gc_vector <double> fib = { 1, 2, 3, 5, 8, 13 };
// verbose and fib are of the same type
vector<int, gc_vector <int>> verbose = fib;
解决方案
可以使用使用C ++ 11模板类型的混叠using
例如这样
template <typename T>
using gc_vector = std::vector<T, gc_allocator<T>>;
<子>注:我知道这是一个老问题,但因为它有相当多的upvotes和它在搜索结果变成了我想它值得更新的答案
其他提示
可以不使用“模板化的typedef”,但可以使用一个方便的类/结构与内型:
template<typename T>
struct TypeHelper{
typedef std::vector<T,gc_allocator<T> > Vector;
};
和然后在代码中使用
TypeHelper<MyType>::Vector v;
TypeHelper<MyType>::Vector::iterator it;
和用于地图类似的东西:
template<typename K,typename V>
struct MapHelper{
typedef std::map<K, V, gc_allocator<K,V> > Map;
};
编辑 - @Vijay:我不知道是否有另一种可能的解决方法,这是我会怎么做;宏可能会给你更紧凑的符号,但我个人不喜欢它:
#define GCVECTOR(T) std::vector<T,gc_allocator<T> >
编辑 - @chmike:请注意,TypeHelper
解决方案的不要求您重新定义构造函数
您可以选择公开继承:
template<class T>
class gc_vector<T> : public std::vector<T, gc_allocator<T> >
{
public:
// You'll have to redeclare all std::vector's constructors here so that
// they just pass arguments to corresponding constructors of std::vector
};
这完全解决您的问题。派生类型到处都可以使用,其中可使用的碱的类型,而且也没有执行开销任何像样的编译器。
这性病::向量具有非虚析构函数可能根据C ++标准导致未定义的行为,如果你曾经尝试通过一个指向基类变量来删除一个派生类变量的事实。
在现实世界中这不应该的问题在这种特殊情况下 - 派生类有没有什么新的比较基类,因此析构函数派生类的添加只是调用基类的析构函数。与偏执进行,端口仔细反正。
如果你从未分配上堆此类变量(和它的典型对堆栈和作为其它类的成员分配矢量变量)非虚析问题不会影响你。
它可以使用宏来完成,如果你愿意你的编译器推到了极限。我做到了,同时实施对Java的“未来”和“可赎回”类C ++等价物。我们的库使用引用计数对象,所以“参考
1. Create your template Classes. Mine are:
template<typename T>
class Callable {
private:
public:
virtual T Call() = 0;
};
template<typename T> CountedFuture : public ReferencedObject {
private:
Callable<T>* theTask;
T theResult;
public:
T Get() {
// Run task if necessary ...
if(task) {
theResult = theTask->Call();
delete theTask;
}
return theResult;
}
};
2. In the application code I'm using references, so I define the macro:
#define Future(T) Reference<CountedFuture<T>>
这样做的好处是使宏做你想要什么,从“模板类型定义”时,缺点是,你不能用“<>”你的类型参数(S)和有没有类型推断。
3. I can now use the Macro wherever I would use a template, like in functions:
Future(char*) DoSomething() { ... }
bool TestSomething(Future(std::string) f) { .... }