سؤال

أحتاج إلى إنشاء خريطة، من الأعداد الصحيحة إلى مجموعات من tuples، tuples في مجموعة واحدة لها نفس الحجم. المشكلة هي أن حجم tuple وأنواع المعلمات يمكن تحديدها في وقت التشغيل، وليس تجميع الوقت. أنا أتخيل شيئا مثل:

std::map<int, std::set<boost::tuple> >

ولكن ليس متأكدا من كيفية القيام بذلك بالضبط، بشكل متزمت باستخدام المؤشرات.

الغرض من ذلك هو إنشاء علاقات مؤقتة (جداول)، ولكل منها مع معرف فريد (مفتاح)، ربما يكون لديك نهج آخر.

هل كانت مفيدة؟

المحلول

الغرض من boost::tuple هو خلط الأنواع التعسفية. إذا، كما تقول،

أنا فقط إدراج الأعداد الصحيحة

ثم يجب عليك استخدام map< int, set< vector< int > > >. وبعد (إذا كنت أنت، سأرمي بعض typedefفي ذلك.)

للإجابة على السؤال الأصلي، رغم ذلك، boost::tuple لا يسمح بأنواع تعسفية في وقت التشغيل. boost::any يفعل. لكن، any لا يدعم المقارنة بحيث يكون هناك المزيد من العمل إذا كنت ترغب في استخدامه في set.

typedef vector< boost::any > tuple;
struct compare_tuple { bool operator()( tuple const &l, tuple const &r ) const {
    assert ( l.size() == r.size() );

    for ( tuple::iterator lit = l.begin(), rit = r.begin();
          lit != l.end(); ++ lit, ++ rit ) {
        assert ( lit->type() == rit->type() );

        if ( lit->type() == typeid( foo ) ) { // find the type and perform "<"
            return boost::any_cast<foo>(*lit) < boost::any_cast<foo>(*rit);
        } else if ( lit->type() == typeid( bar ) ) {
            return boost::any_cast<bar>(*lit) < boost::any_cast<bar>(*rit);
        } /* etc; you will need to enumerate all the types you can insert */
    }
} };

typedef std::map< int, std::set< tuple, compare_tuple > > main_map;

نصائح أخرى

كملاحظة جانبية حديثة (مع وجود إجابات سابقة حوالي عام 2010)، ستكون قوالب Variadic اليوم مفيدة لهذا:

template<typename... Args> //Accept any number of arguments and types
auto MyFunction(std::tuple<Args...> &T)->void
{
   //Do stuff...
}

يمكنك فقط تخزين هذه المجموعات المختلفة في نفس المجموعة إذا كان لديك بعض الفئة الأساسية المشتركة لهم. يمكنك كتابة واجهة مجردة، ثم قم بتنفيذ ذلك لكل نوع من الطاولة / Tuple. المشكلة هي أنه عادة ما تميل مثل هذه الواجهات إلى أن تكون فوضويا للغاية، وربما يكون لديك انفجار فئة إذا كان لديك العديد من أنواع الطاولة / TUPLES. boost.any. قد تكون مفيدة لمثل هذه الواجهة (نظرا لأنك تضطر إلى التعامل مع أنواع البيانات المختلفة بشكل حيوي).

إذا كانت أنواع المعلمات تحتوي على شيء مشترك، والتقاط ذلك إلى فئة قاعدة مجردة وجعل Tuple يحتوي على مؤشرات على الفئة الأساسية هذه:

class MyParamBase {
public:
    virtual int getFoo() = 0;
    virtual void setFoo(int) = 0;
};

std::map<int, std::set<MyParamBase*> > container;

(دفعة :: tuple حذفت للإيجاز. لست متأكدا لماذا تحتاج إلى مجموعة من tuples.)

يمكنك بعد ذلك استخلاص أنواع المعلمات الخرسانية من MyParambase وإنشاءها وإدخالها في الخريطة:

class SomeParam: MyParamBase {
public:
    virtual int getFoo() { ... }
    virtual void setFoo(int a) { ... }
};

std::set<MyParamBase*> some_set;
some_set.insert(new SomeParam());
container[123] = some_set;

إذا لم يكن لها أنواع المعلمات شائعة - لا تضعها في نفس الخريطة. من المحتمل جدا أنهم لا ينتمون معا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top