سؤال

أنا باستخدام libgc ، جامع القمامة C و C++.لجعل الخاصة بلبنان حاويات القمامة تحصيلها يجب على المرء أن استخدام 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;
};

تحرير - @فيجاي:أنا لا أعرف إذا كان هناك آخر ممكن الحل هكذا أود أن تفعل ذلك ؛ ماكرو قد تعطيك أكثر إحكاما التدوين ، ولكن أنا شخصيا لن ترغب في ذلك:

#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 ++ إذا كنت من أي وقت مضى في محاولة لحذف متغير فئة مشتقة من خلال مؤشر إلى متغير الفئة الأساسية.

في العالم الحقيقي هذا لا ينبغي أن يهم في هذه الحالة بالذات - فئة مشتقة لها شيئا جديدا يضاف بالمقارنة مع الفئة الأساسية، وبالتالي فإن المدمر لفئة مشتقة يدعو فقط المدمر للفئة الأساسية. المضي قدما مع جنون العظمة، ومنفذ بعناية على أي حال.

إذا لم تخصيص هذه المتغيرات الفئة على كومة (وهذا نموذجي لتخصيص المتغيرات ناقلات على كومة وكأعضاء في فئات أخرى) لا يؤثر على مشكلة المدمر غير ظاهري لك.

ويمكن ان يتم ذلك مع MACRO، إذا كنت على استعداد لدفع مترجم لحدوده. فعلت ذلك مع تنفيذ حكمه C ++ ل "المستقبل" جافا والطبقات "المستحقة". يستخدم مكتبتنا الكائنات عد إشارة، وذلك "المرجعي " هو في حد ذاته فئة القالب حيث "T" مشتقة من "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>>

وجمال هذا هو أن هو أن ماكرو يفعل بالضبط ما كنت تريد من "typedef وقالب"، سلبيات هو أن لا يمكنك استخدام "<>" للمعلمة نوع الخاص بك (ق) وهناك اي نوع الاستدلال.

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) { .... }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top