Приоритет вызова функции в выходном потоке - PullRequest
3 голосов
/ 18 марта 2020

Итак, у меня есть следующий класс:

typedef double decimal;

class Ratio {
  int num, den;
  decimal val;

public:
  Ratio() { num = 1, den = 1, val = (decimal)num / den; }

  Ratio update(int a, int b) {
    num *= a, den *= b;
    val = (decimal)num / den;
    return *this;
  }

  decimal v(void) { return val; }

  friend ostream &operator<<(ostream &out, const Ratio &R) {
    return (out << R.num << ':' << R.den);
  }
};

Когда я использую функции-члены в выходном потоке как:

cout<<"R = "<<R.update(2,1)<<"\tvalue = "<<R.v();

, где R имеет тип Ratio, функция в правом конце вызывается первым, поэтому отображается обновленное соотношение, но не обновленное значение:

R = 2:1    value = 1

Я преодолел это, разделив поток на две части:

cout<<"R = "<<R.update(2,1), cout<<"\tvalue = "<<R.v();

, чтобы Я "заставляю" .update () быть вызванным первым. Есть ли другой способ добиться этого, используя только один поток для вывода?

Ответы [ 2 ]

3 голосов
/ 18 марта 2020

Поскольку в c ++ нет гарантированного порядка оценки, он не будет работать без разделения его на отдельные части, как вы делали в своем исправлении.

Цитирование из cppreference

В C ++ отсутствует концепция оценки слева направо или справа налево. Это не следует путать с ассоциативностью операторов слева направо и справа налево: выражение a () + b () + c () анализируется как (a () + b ()) + c () из-за ассоциативности оператора + слева направо, но вызов функции c может оцениваться первым, последним или между a () или b () во время выполнения

Как указал пользователь @super, начиная с c ++ 17 теперь определяется порядок вычисления операторов сдвига. Это скрыто в пуле 19) правил на странице, на которую я ссылался выше. Итак, если вы можете c ++ 17, все готово.

0 голосов
/ 18 марта 2020

Поместите значение также в << перегруженную функцию, например </p>

 friend ostream& operator<<(ostream &out,const Ratio &R){return (out<<"R = "<<R.num<<':'<<R.den<<"\tvalue = "<<R.val);}

Сейчас

#include<iostream>

using namespace std;

typedef double decimal;

class Ratio{
    int num,den;
    decimal val;
public:
    Ratio(){num=1,den=1,val=(decimal)num/den;}
    Ratio update(int a,int b){
        num*=a,den*=b;
        val=(decimal)num/den;
        return *this;
    }
    friend ostream& operator<<(ostream &out,const Ratio &R){return (out<<"R = "<<R.num<<':'<<R.den<<"\tvalue = "<<R.val);}
};

int main()
{
    Ratio R;

    cout<<R.update(2,1)<<endl;

}

Вывод:

  R = 2:1 value = 2

  Process returned 0 (0x0)   execution time : 0.382 s
  Press any key to continue.
...