كيفية الحصول على عنوان وظيفة العضو للفئة المحلية المحددة في الوظيفة (C ++)

StackOverflow https://stackoverflow.com/questions/2152845

سؤال

أحاول القيام بما يلي: الحصول على عنوان وظيفة العضو من فصل تم تعريفه محليًا في وظيفة ما.

class ConnectionBase
{
};

template class<EventType, SinkType>
class ConnectionImpl : public ConnectionBase
{
public:
typedef void (SinkType::*EventCallback)(EventType const&);
};


template<class EventType>
class Source
{
    template <class SinkType>
    boost::shared_ptr<ConnectionBase> setupCallback(typename ConnectionImpl<EventType, SinkType>::EventCallback func, SinkType* sink)
    {
    // do the actual connecting.
    }
};

class SomeClass
{
public:
    void someFunction(int const& event){}
}

class SomeUnitTest
{
public:
    void someTest()
    {
        class NestedClass 
        {
        public:
            void someFunction(int const& event){}
        };

       NestedClass nc;

       //Try#1 - This does not work
       setupCallback<int, NestedClass>(&NestedClass::someFunction, &nc);

       //Try #2 - This also does not work
       setupCallback<int, NestedClass>(&SomeUnitTest::someTest::NestedClass::someFunction, &nc);

       //Try #3 - Following the GCC error output, I tried this
       setupCallback<int, NestedClass>(&SomeUnitTest::someTest()::NestedClass::someFunction, &nc);

       SomeClass sc;

       //This works fine, as expected
       setupCallback<int, SomeClass>(&SomeClass::someFunction, &sc);

    }
};

جرب رقم 2 و #3 يخلطون تمامًا مع مجلس التعاون الخليجي ، ليس لديه أي فكرة عما أحاول القيام به. جرب #1 ينتج رسالة خطأ أكثر فائدة تقول أنه لا يوجد setupCallback يأخذ النموذج "SetupCallback (void (SomeUnittest :: Somethest () :: nestedclass :: somefunction ::*) ، إلخ) وهو كيف ولدت المحاولة رقم 3.

لا يمكنني حقًا العثور على الكثير من المعلومات حول الفصول المحددة داخل وظيفة ما ، هل يعرف أي شخص بناء الجملة الصحيح لهذا الغرض ، وربما يكون لديك مورد يناقش هذا الموضوع؟

حسنًا ، يبدو أن هذا قد تم تسويته ، كما أشار كلا الملصقات ، وليس للصفوف المحلية أي صلة ، لا يمكن أن تعمل. الآن مع العلم هذا ، وجدت هذا المقال الذي يناقش هذا ، لأي شخص آخر يواجه هذه المشكلة ويتعثر عبر هذا السؤال: http://www.informit.com/guides/content.aspx؟g=cplusplus&seqnum=420

تحرير: توضيح SetupCallback () ، مثال على العمل مع فئة أكثر انتظامًا
تحرير رقم 2: صياغة محدثة لتغيير "متداخل" إلى "محلي". تمت إضافة المزيد من التفاصيل لـ SetupCallback.
تحرير #3: روابط إضافة إلى معلومات Furhter. شكرا لكم جميعا.

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

المحلول

لا أعرف عن مشكلة بناء الجملة ، يجب أن تنطبق قواعد الوصول المعتادة - ولكن هناك مشكلة أخرى هنا إذا كان ذلك سيعمل لأن وظائف الأعضاء هذه ليس لها أي صلة.
لقبول الأنواع المحلية على الإطلاق ، setupCallback() يجب أن تكون وظيفة قالب - ولكن لا يُسمح بوسائط نوع القالب دون أي ارتباط.

§3.5/8 يقول:

الأسماء التي لا تغطيها هذه القواعد ليس لها أي ارتباط. علاوة على ذلك ، باستثناء ما لوحظ ، فإن الاسم المعلن في النطاق المحلي (3.3.2) ليس له أي صلة.

لا يتم تغطية أعضاء الفصول المحلية هناك. §9.3/3 يوضح ذلك:

وظائف الأعضاء في فئة محلية (9.8) ليس لها أي صلة.

مختصرة القصة الطويلة: لا تستخدم وظائف الأعضاء لفئة محلية كعمليات عروض ، استخدم فئة غير محلية بدلاً من ذلك.

نصائح أخرى

أنت متغير القبضة هو الصحيح طالما تم النظر في المسألة المحددة لأخذ العنوان. لا توجد قيود على أخذ عنوان وظائف الأعضاء في الفصول المحلية. بناء الجملة المناسب هو المعتاد

&NestedClass::someFunction

هذا كل شيء. يمكنك محاولة حفظه في مؤشر وسيطة في الكود الخاص بك

void (NestedClass::*ptr)() = &NestedClass::someFunction;

وأنا متأكد من أن المترجم الخاص بك سوف يقبله.

ومع ذلك ، فإن المشكلة التي أظن أنها موجودة في الكود الخاص بك لا علاقة لها على الإطلاق بالطريقة الصحيحة لأخذ عنوان وظيفة العضو. يتعلق الأمر بالطريقة التي تدور حولها المعلمة الأولى setupCallback تم إعلانه. بما أنك تقول إنه يعمل مع &SomeClass::someFunction كحجة أول ، أتوقع setupCallback ليتم إعلانها باسم

void setupCallback(void (SomeClass::*cb)(), SomeClass *p); // one possibility

أي هو المتشددين لتوقع مؤشر لعضو SomeClass على وجه التحديد. لا يمكنك تزويد مؤشر لعضو NestedClass في حين أن. NestedClass لا علاقة له تماما SomeClass وشركات لأعضاء NestedClass لا تتوافق تمامًا مع مؤشرات أعضاء SomeClass. هذا هو السبب في أنه لن يجمع.

ما لم يكن هناك شيء لا تعرضه لنا (مثل setupCallback كونك قالب وظيفة ربما؟ أو تم تحميله بشكل زائد لأنواع مختلفة من المعلمات؟) ، ما تحاول القيام به هو ببساطة من المستحيل تحقيقه بغض النظر عن كيفية أخذ عنوان العضو ، طالما NestedClass لا يزال غير مرتبط SomeClass. وظيفة setupCallback تم تصميمه للعمل مع SomeClass و SomeClass فقط.

توفير المزيد من المعلومات حول setupCallback. كيف تم إعلانها؟

لاحظ أنه إذا كان setupCallback يُعلن كقالب دالة معدومه بواسطة نوع الفئة ، كما في

template <class T> void setupCallback(void (T::*cb)(), T* p);

ثم لن تتمكن من استخدام الفصل المحلي NestedClass كوسيطة قالب للمعلمة T. في هذه الحالة حقيقة أن الخاص بك NestedClass ليس له أي ارتباط يحدث بالفعل. ولكن ، مرة أخرى ، لا علاقة له بأخذ عنوان العضو ، ولكن بسبب حقيقة أنه لا يمكن استخدام الطبقات التي لا توجد ارتباط كوسائط قالب في C ++.

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