تسمى وظيفة محملة الزائد مع معلمة واحدة ، لكنني اعتقدت أنني مررت اثنين

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

سؤال

لقد قمت مؤخرًا بإعادة تمثيل رمز مثل هذا (MyClass ل MyClassR).

#include <iostream>

class SomeMember
{
public:
  double m_value;

  SomeMember() : m_value(0) {}
  SomeMember(int a) : m_value(a) {}
  SomeMember(int a, int b)
  : m_value(static_cast<double>(a) / 3.14159 +
            static_cast<double>(b) / 2.71828)
  {}
};


class MyClass
{
public:
SomeMember m_first, m_second, m_third;

MyClass(const bool isUp, const int x, const int y)
{
  if (isUp)
  {
    m_first = SomeMember(x);
    m_second = SomeMember(y);
    m_third = SomeMember(x, y);
  }
  else
  {
    m_first = SomeMember(y);
    m_second = SomeMember(x);
    m_third = SomeMember(y, x);
  }
}
};


class MyClassR
{
public:
SomeMember m_first, m_second, m_third;

MyClassR(const bool isUp, const int x, const int y)
: m_first(isUp ? x : y)
, m_second(isUp ? y : x)
, m_third(isUp ? x, y : y, x)
{
}
};


int main()
{
    MyClass a(true, 1, 2);
    MyClassR b(true, 1, 2);

    using namespace std;
    cout.precision(10);
    cout
        << "a:" << endl
        << "\tfirst: " << a.m_first.m_value 
        << "\tsecond: " << a.m_second.m_value 
        << "\tthird: " << a.m_third.m_value << endl;

    cout
        << "b:" << endl
        << "\tfirst: " << b.m_first.m_value
        << "\tsecond: " << b.m_second.m_value
        << "\tthird: " << b.m_third.m_value << endl;

    return 0;
}
  • ما هو الخطأ ،
  • لماذا يتم تجميع (اختبار مع VC6 وكذلك VC9 تحذير المستوى 4: لا شكاوى) و
  • ما هي الطريقة الصحيحة للقيام بذلك؟

أنا (افترض) لدي بالفعل كل هذه الإجابات ، لكنني أعتقد أنه من المثير للاهتمام ومشاركة المشاركة.

تحديث
الرمز الممتد بحيث يكون "نسخ & لصق وتنفيذ". لم يعطيني VC9 أي شكاوى إما هكذا VC6 ليس هو المشكلة هنا.
للاكتمال ، الإخراج هو:

a:
        first: 1        second: 2       third: 1.054069532
b:
        first: 1        second: 2       third: 1.004499999
هل كانت مفيدة؟

المحلول

لست متأكدًا مما تتوقعه بالضبط ولكن لنبدأ ...

  • أولاً ، Ditch VC6. بجدية. يعد استخدامها مشكلة كبيرة لأنها ليست مجرد معايير تتوافق وتمنع الكثير من الخيارات. استخدامه بشكل صحيح مثل لعب الروليت الروسي.

  • مُنشئك m_third لا تفعل ما تعتقد أنه يفعل. لا يمكنك كتابة تعبير مشروط مثل هذا: "عدة معلمات" ليست صالحة التعبير في C ++ ، ويعمل المشغل الشرطي على التعبيرات.

  • يتجمع الرمز لأنه لا يزال صيح, ، لا يفعل ما تريده. بدلاً من استخدام "عدة معلمات" ، يقوم بتقييم مشغل نقطة التسلسل (,) الذي يأخذ فقط الاخير قيمة التعبير ، لذلك فإن الشرطية الخاصة بك تعادل فعليًا: isUp ? y : x

  • الطريقة الصحيحة هي الاستخدام اثنين الشرطية: m_third(isUp ? x : y, isUp ? y : x)

  • المُنشئ الثالث ل SomeMember من الخطأ ، قد تفيض القيمة ، مما يؤدي إلى قيمة سلبية - أشك بشدة في أن هذا ما تريده.

نصائح أخرى

m_third(isUp ? x, y : y, x)

هذا يبدو من الخطأ أن تكون. الأول x هو تعبير لا معنى له لأنه لا يوجد له آثار جانبية ولا يتم استخدام النتيجة ، ثم جانبي : لها نفس القيمة والآثار الجانبية هكذا ?: يمكن التخلص منها كتعبير قبل ? أيضا ليس له آثار جانبية.

m_third(y, x)

ولكن الآن لا يفعل ما يفعله الرمز الأصلي ... هل هذا هو الخطأ؟

ما هو الخطأ ما هي الطريقة الصحيحة للقيام بذلك؟

أعتقد أن نيتك هي إظهار نوع من الاستخدام الساذج لمشغل الفاصلة مع Ternary؟ ، ربما هناك بعض أولوية Gotcha ذكية وغير متوقعة ، لكنني أعتقد أن الكود مصطنع تمامًا. إذا كانت هذه هي النقطة ، فأنا أقول أن "الطريقة الصحيحة للقيام بذلك" هي عدم استخدام C ++ أو تعلمها أولاً قبل استخدامها. نعم ، إنه يحتوي على العديد من الإنشاءات التي قد تبدو مثل "المراوغات" ويمكنك إنشاء الكثير من التعليمات البرمجية المظهر الغريبة المقبولة من قبل برنامج التحويل البرمجي. باستخدام C ++ ، أود أن أقول إنك يُفترض أن تعرف الأدوات.

لماذا يتم تجميع

لأنه لا يحتوي على خطأ وهو رمز C ++ صحيح بدون أي غموض.

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