templated typedef?

前端 未结 4 1484
我寻月下人不归
我寻月下人不归 2020-12-04 19:10

I\'m using libgc, a garbage collector for C and C++. To make STL containers garbage collectible one must use the gc_allocator.

Instead of writing

s         


        
相关标签:
4条回答
  • 2020-12-04 19:47

    It can be done with a MACRO, if you're willing to push your compiler to its limits. I did it while implementing C++ equivalents for Java's "Future" and "Callable" classes. Our library uses reference-counted objects, so "Reference<T>" is itself a template class where "T" derives from "ReferencedObject".

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

    The beauty of this is that is that the Macro does exactly what you'd want from a "template typedef", the downsides being that you can't use "<>" for your type parameter(s) and there is no type inference.

    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) { .... }
    
    0 讨论(0)
  • 2020-12-04 19:58

    You cannot use a "templated typedef", but you can use a convenience class/struct with an inner type:

    template<typename T>
    struct TypeHelper{
        typedef std::vector<T,gc_allocator<T> > Vector;
    };
    

    and then use in your code

    TypeHelper<MyType>::Vector v;
    TypeHelper<MyType>::Vector::iterator it;
    

    And something similar for the map:

    template<typename K,typename V>
    struct MapHelper{
        typedef std::map<K, V, gc_allocator<K,V> > Map;
    };
    

    EDIT - @Vijay: I don't know if there's another possible workaround, that's how I would do it; a macro might give you a more compact notation, but personally I wouldn't like it:

    #define GCVECTOR(T) std::vector<T,gc_allocator<T> >
    

    EDIT - @chmike: Please note that the TypeHelper solution does not require you to redefine constructors!

    0 讨论(0)
  • 2020-12-04 20:06

    You can use C++11 templated type aliasing using using e.g. like this

    template <typename T>
    using gc_vector = std::vector<T, gc_allocator<T>>;
    

    Note: I know this is an old question but since it has quite many upvotes and as it turns up in search results I thought it deserved an updated answer.

    0 讨论(0)
  • 2020-12-04 20:12

    You can publicly inherit:

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

    This solves your problem completely. The derived type can be used everywhere where the base type can be used, and there's no implementation overhead with any decent compiler.

    The fact that std::vector has non-virtual destructor might lead to undefined behaviour according to C++ standard if you ever try to delete a derived class variable through a pointer to base class variable.

    In real world this shouldn't matter in this particular case - the derived class has nothing new added compared to the base class and therefore the destructor for the derived class just calls the destructor for the base class. Proceed with paranoia, port carefully anyway.

    If you never allocate this class variables on heap (and it's typical to allocate vector variables on stack and as members of other classes) the non-virtual destructor problem doesn't affect you.

    0 讨论(0)
提交回复
热议问题