لا يمكن للمشغل الشرطي حل مؤشرات وظيفة العضو المحملة بشكل زائد

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

سؤال

أواجه مشكلة بسيطة في التعامل مع المؤشرات لوظائف الأعضاء المثقلة في C++.الكود التالي يجمع بشكل جيد:

class Foo {
public:
    float X() const;
    void X(const float x);
    float Y() const;
    void Y(const float y);
};

void (Foo::*func)(const float) = &Foo::X;

لكن هذا لا يتم تجميعه (يشكو المترجم من أن الأحمال الزائدة غامضة):

void (Foo::*func)(const float) = (someCondition ? &Foo::X : &Foo::Y);

من المفترض أن يكون هذا أمرًا متعلقًا بفرز المترجم لقيمة الإرجاع للعامل الشرطي بشكل منفصل عن نوع مؤشر الوظيفة؟يمكنني حل هذه المشكلة، ولكنني مهتم بمعرفة كيف تقول المواصفات أنه من المفترض أن يعمل كل هذا لأنه يبدو غير بديهي إلى حد ما وإذا كانت هناك طريقة للتغلب عليه دون الرجوع إلى 5 أسطر من if-then-else .

أنا أستخدم MSVC++، إذا كان ذلك يحدث أي فرق.

شكرًا!

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

المحلول

من القسم 13.4/1 ("عنوان الوظيفة المحملة بشكل زائد،" [over.over]):

يتم حل استخدام اسم دالة محمّلة بشكل زائد بدون وسيطات في سياقات معينة لوظيفة، أو مؤشر لوظيفة أو مؤشر لوظيفة عضو لوظيفة معينة من مجموعة التحميل الزائد.يعتبر اسم قالب الوظيفة لتسمية مجموعة من الوظائف المحملة بشكل زائد في مثل هذه السياقات.الوظيفة المحددة هي التي يتطابق نوعها مع نوع الهدف المطلوب في السياق.يمكن أن يكون الهدف

  • كائن أو مرجع تتم تهيئته (8.5، 8.5.3)،
  • الجانب الأيسر من المهمة (5.17)،
  • معلمة الدالة (5.2.2)،
  • معلمة عامل محدد من قبل المستخدم (13.5)،
  • القيمة المرجعة لوظيفة أو وظيفة عامل تشغيل أو تحويل (6.6.3) أو
  • تحويل نوع صريح (5.2.3، 5.2.9، 5.4).

يمكن أن يسبق اسم وظيفة التحميل الزائد بـ & المشغل أو العامل.لا يجوز استخدام اسم دالة مثقلة بدون وسائط في سياقات أخرى غير تلك المذكورة.[ملحوظة: يتم تجاهل أي مجموعة زائدة من الأقواس المحيطة باسم الوظيفة المحملة بشكل زائد (5.1).]

ال هدف كنت تأمل أن يتم اختيارك من القائمة أعلاه، وهو الكائن الأول الذي تتم تهيئته.ولكن هناك عامل شرطي في الطريق، وتحدد العوامل الشرطية أنواعها من معاملاتها، وليس من أي نوع هدف.

نظرًا لأنه تم تضمين تحويلات النوع الصريحة في قائمة الأهداف، يمكنك كتابة كل تعبير مؤشر عضو في التعبير الشرطي بشكل منفصل.سأقوم بعمل typedef أولاً:

typedef void (Foo::* float_func)(const float);
float_func func = (someCondition ? float_func(&Foo::X) : float_func(&Foo::Y));

نصائح أخرى

وجرب:

    void (Foo::*func1)(const float) = &Foo::X;
    void (Foo::*func2)(const float) = &Foo::Y;

    void (Foo::*func3)(const float) = (someCondition ? func1:func2);

والمشكلة هي نوع نتيجة للtrinary المشغل يتم تحديدها من قبل حججها.
في هذه الحالة لا يمكن تحديد نوع نتيجة لأن أنواع المدخلات ديها خيارات multuiple. انها ليست حتى يتم تحديد نوع المشغل trinary أنها ستحاول المهمة.

مثال:

class Foo {
public:
    void X(float x) {}
    void Y(float y)  {}
    float X() const;
};
typedef void (Foo::*Fff)(float);
Fff func = &Foo::X;
Fff func2 = true ? (Fff)&Foo::X : (Fff)&Foo::Y;

int main(){
    return 0;
}

وتحتاج للادلاء وفو :: X فورا من أجل حل الزائد. لاحظ أنه إذا كنت التعليق خارج تطفو فوق طاقتها X ()، لا تحتاج للقيام بذلك.

ويبدو أن المترجم ليس ذكيا بما يكفي للاستدلال على المطلوب نوع عودة تعبير الثلاثي (هذا قد يكون خطأ).

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