كيفية الحصول على عنوان وظيفة العضو للفئة المحلية المحددة في الوظيفة (C ++)
-
23-09-2019 - |
سؤال
أحاول القيام بما يلي: الحصول على عنوان وظيفة العضو من فصل تم تعريفه محليًا في وظيفة ما.
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 ++.