Перегруженная функция вызывается с одним параметром, но я думал, что передал два - PullRequest
2 голосов
/ 19 марта 2010

Я недавно рефакторил код, подобный этому (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

Ответы [ 3 ]

8 голосов
/ 19 марта 2010

Я не уверен, что именно вы ожидаете, но давайте начнем ...

  • Прежде всего, канаву VC6. Серьезно. Использовать его - огромная проблема, поскольку он просто не соответствует стандартам и исключает множество вариантов.Использовать его правильно - все равно что играть в русскую рулетку.

  • Ваш конструктор m_third не делает то, что вы думаете, что он делает.Вы не можете написать условное выражение, например: «несколько параметров» не является допустимым выражением в C ++, а условный оператор работает с выражениями.

  • Код компилируетсяпотому что он все еще правильный , он просто не делает то, что вы хотите.Вместо использования «нескольких параметров» он оценивает оператор точки последовательности (,), который просто принимает значение выражения last , поэтому ваше условное выражение фактически эквивалентно: isUp ? y : x

  • Правильный способ - использовать два условия: m_third(isUp ? x : y, isUp ? y : x)

  • Третий конструктор SomeMember неверен, значениеможет переполниться, давая отрицательное значение - я очень сомневаюсь, что это то, что вы хотите.

2 голосов
/ 19 марта 2010
m_third(isUp ? x, y : y, x)

Это выглядит неправильно. Первое x является бессмысленным выражением, поскольку оно не имеет побочных эффектов и результат не используется, затем две стороны : имеют одинаковое значение и побочные эффекты, поэтому ?: можно исключить как выражение перед ? также не имеет побочных эффектов.

m_third(y, x)

Но теперь он не делает то, что делает оригинальный код ... это ошибка?

0 голосов
/ 19 марта 2010

В чем ошибка Как правильно это сделать?

Полагаю, вы намереваетесь показать какое-то наивное использование оператора запятой в сочетании с троичным? Возможно, есть какой-то умный и неожиданный приоритет оператора, который должен быть скрыт, но я думаю, что код абсолютно искусственный. Если это так, то я бы сказал, что «правильный способ сделать это» - не использовать C ++ или сначала изучить его перед использованием. Да, у него много конструкций, которые могут выглядеть как «причуды», и вы можете создать много странного кода, принятого компилятором. Используя C ++, я бы сказал, что вы должны знать инструменты.

Почему компилируется

Поскольку он не содержит ошибок и является правильным кодом C ++ без двусмысленностей.

...