Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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

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
模板化typedef? 我使用的是LBGC,一个C和C++的垃圾回收器。 要使STL容器可垃圾回收,必须使用gc_分配器_C++_Templates_C++11_Typedef - Fatal编程技术网

模板化typedef? 我使用的是LBGC,一个C和C++的垃圾回收器。 要使STL容器可垃圾回收,必须使用gc_分配器

模板化typedef? 我使用的是LBGC,一个C和C++的垃圾回收器。 要使STL容器可垃圾回收,必须使用gc_分配器,c++,templates,c++11,typedef,C++,Templates,C++11,Typedef,而不是写作 std::vector<MyType> std::vector 一个人必须写作 std::vector<MyType,gc_allocator<MyType> > std::vector 有没有办法定义类似 template<class T> typedef std::vector<T,gc_allocator<T> > gc_vector<T>; template typedef std

而不是写作

std::vector<MyType> 
std::vector 一个人必须写作

std::vector<MyType,gc_allocator<MyType> >
std::vector 有没有办法定义类似

template<class T> typedef std::vector<T,gc_allocator<T> > gc_vector<T>;
template typedef std::vector gc_vector;
我前段时间查过了,发现这是不可能的。但我可能错了,或者有别的办法

以这种方式定义地图尤其令人不快

std::map<Key,Val> 
std::map
变成

std::map<Key,Val, std::less<Key>, gc_allocator< std::pair<const Key, Val> > >
std::map>
编辑:尝试使用宏后,我发现以下代码将其打断:

#define gc_vector(T) std::vector<T, gc_allocator<T> >
typedef gc_vector( std::pair< int, float > ) MyVector;
定义gc向量(T)std::vector typedef gc_向量(std::pair)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; 
//使用我的分配器的标准向量
模板
使用gc_vector=std::vector;
//使用My_alloc分配元素
gc_向量fib={1,2,3,5,8,13};
//verbose和fib属于同一类型
向量冗余=fib;
不能使用“模板化的typedef”,但可以使用具有内部类型的方便类/结构:

template<typename T>
struct TypeHelper{
    typedef std::vector<T,gc_allocator<T> > Vector;
};
模板
结构类型助手{
typedef std::向量;
};
然后在代码中使用

TypeHelper<MyType>::Vector v;
TypeHelper<MyType>::Vector::iterator it;
TypeHelper::Vector v;
TypeHelper::Vector::iterator;
地图上也有类似的东西:

template<typename K,typename V>
struct MapHelper{
    typedef std::map<K, V, gc_allocator<K,V> > Map;
};
模板
结构映射帮助器{
typedef std::map;
};
编辑-@Vijay:我不知道是否还有其他可能的解决办法,那就是我会怎么做;宏可能会提供更紧凑的表示法,但我个人不喜欢它:

#define GCVECTOR(T) std::vector<T,gc_allocator<T> >
定义GCVECTOR(T)std::vector
编辑-@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
};
模板
类gc_向量:public std::vector
{
公众:
//您必须在此处重新声明所有std::vector的构造函数,以便
//它们只是将参数传递给std::vector的相应构造函数
};
这完全解决了你的问题。派生类型可以在任何可以使用基类型的地方使用,并且没有任何合适的编译器的实现开销

<> Pt>:如果您尝试通过基类变量指针删除派生类变量,则STD::vector具有非虚析构函数可能会导致根据C++标准的未定义行为。 在现实世界中,在这种特殊情况下,这并不重要——与基类相比,派生类没有添加任何新的内容,因此派生类的析构函数只调用基类的析构函数。不管怎么说,还是要小心处理妄想症


如果您从未在堆上分配此类变量(通常在堆栈上分配向量变量并将其作为其他类的成员),则非虚拟析构函数问题不会影响您。

如果您愿意将编译器推向极限,可以使用宏来完成。我在实现java的“将来”和“可调用”类的C++等效项时做到了这一点。我们的库使用引用计数对象,因此“reference”本身就是一个模板类,其中“T”派生自“ReferencedObject”


您可以使用
使用C++11模板化类型别名,例如

template <typename T>
using gc_vector = std::vector<T, gc_allocator<T>>;
模板
使用gc_vector=std::vector;

注意:我知道这是一个老问题,但由于它有相当多的赞成票,而且当它出现在搜索结果中时,我认为它应该得到一个更新的答案。

不,在这种情况下,这并不重要。与基数据相比,派生数据没有新的数据成员,因此基数据的删除*和派生数据的删除*之间没有区别。派生构造函数只是调用基本构造函数。@sharptooth-这很重要-你的建议可能会发生,但标准说它是UB。好吧,我希望标准不是逻辑和常识的替代品。你能举个例子说明为什么这种情况会导致问题吗?依赖未定义的行为是没有常识的。它本质上是不可移植的,不管一个实现执行什么操作。因此,是的,在这种情况下,标准是“常识”的替代品。很难给出一个未定义行为的例子。一个符合要求的实现可以删除硬盘上的内容。如果您在所有合理的系统上都尝试了它,并且它按预期工作,那么您可以在知道它未定义的情况下自由地使用它。不过,作为一项规则,我会避开UB。是的,有。“继承要整洁得多,这正是问题所在”。@sharptooth:在这种情况下,继承的确为您提供了最好的表示法,并避免了使用宏,但正如您在对答案的评论中指出的那样,它的用法是有争议的。我耐心地等待任何潜在问题的证据。我将选择宏的答案,因为它是“最好的”解决方案其他两种解决方案(继承或内部类/结构)都需要重新定义构造函数。宏将在typedef指令中使用。您可以在回答中添加模板typedef(也称为模板别名)将包含在C++0x中(但是,gcc还不支持它)。为什么说
TypeHelper
解决方案要求您重新定义构造函数?这只不过是typedef上的一个快捷方式而已……哎呀,你说得对。很高兴你在回答中澄清了这一点。我被告知C++0X将通过使用“using”关键字提供更好的解决方案。你知道这将如何工作吗?C++0x将提供模板别名,这将提供一种方法来完全实现你想要的@WurmD哪个更新的答案?我将接受的答案改为提供C++11方法的答案。那是你问我的吗?
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) { .... }
template <typename T>
using gc_vector = std::vector<T, gc_allocator<T>>;