Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 07e57f91 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

Another typo in recommended...

parent f0f79d3d
Branches
Tags
No related merge requests found
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# [Getting started in C++](./) - [Operators](./0-main.ipynb) - [Stream operators](./3-Stream.ipynb) # [Getting started in C++](./) - [Operators](./0-main.ipynb) - [Stream operators](./3-Stream.ipynb)
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
<h1>Table of contents<span class="tocSkip"></span></h1> <h1>Table of contents<span class="tocSkip"></span></h1>
<div class="toc"><ul class="toc-item"><li><span><a href="#Operator-<<" data-toc-modified-id="Operator-<<-1">Operator &lt;&lt;</a></span></li><li><span><a href="#Operator->>" data-toc-modified-id="Operator->>-2">Operator &gt;&gt;</a></span></li></ul></div> <div class="toc"><ul class="toc-item"><li><span><a href="#Operator-<<" data-toc-modified-id="Operator-<<-1">Operator &lt;&lt;</a></span></li><li><span><a href="#Operator->>" data-toc-modified-id="Operator->>-2">Operator &gt;&gt;</a></span></li></ul></div>
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Operator << ## Operator <<
So far, we have very often defined methods and/or functions named `Print()` to provide a visual printing of the content of a class. So far, we have very often defined methods and/or functions named `Print()` to provide a visual printing of the content of a class.
However, it's even better if we could use the `<<` syntax directly, and the way to do so is to provide an overload of `operator<<`. However, it's even better if we could use the `<<` syntax directly, and the way to do so is to provide an overload of `operator<<`.
The recommanded way to implement it is to use under the hood a `Print(std::ostream&)` (or whatever you want to call it): The recommended way to implement it is to use under the hood a `Print(std::ostream&)` (or whatever you want to call it):
**Xeus-cling** issue: cling doesn't accept operator definition outside of class; please use [@Coliru](https://coliru.stacked-crooked.com/a/04f59249cce6c131) **Xeus-cling** issue: cling doesn't accept operator definition outside of class; please use [@Coliru](https://coliru.stacked-crooked.com/a/04f59249cce6c131)
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` C++17 ``` C++17
// Doesn't run on Xeus-cling due to definition of an operator outside of a class // Doesn't run on Xeus-cling due to definition of an operator outside of a class
// A ticket has been opened for this: https://github.com/QuantStack/xeus-cling/issues/214 // A ticket has been opened for this: https://github.com/QuantStack/xeus-cling/issues/214
#include <iostream> #include <iostream>
class Rational class Rational
{ {
public : public :
explicit Rational(int numerator, int denominator); explicit Rational(int numerator, int denominator);
// Might even be private; in which case friendship needs to be declared // Might even be private; in which case friendship needs to be declared
void Print(std::ostream& out) const; void Print(std::ostream& out) const;
private : private :
int numerator_ = 0; int numerator_ = 0;
int denominator_ = 0; int denominator_ = 0;
}; };
Rational::Rational(int numerator, int denominator) Rational::Rational(int numerator, int denominator)
: numerator_(numerator), : numerator_(numerator),
denominator_(denominator) denominator_(denominator)
{ } { }
void Rational::Print(std::ostream& out) const void Rational::Print(std::ostream& out) const
{ {
out << numerator_ << " / " << denominator_; out << numerator_ << " / " << denominator_;
} }
std::ostream& operator<<(std::ostream& out, const Rational& r) std::ostream& operator<<(std::ostream& out, const Rational& r)
{ {
r.Print(out); // see how the bulk of the work is done by the 'Print()' method! r.Print(out); // see how the bulk of the work is done by the 'Print()' method!
return out; return out;
} }
int main() int main()
{ {
Rational r1(22, 7); Rational r1(22, 7);
Rational r2(77, 17); Rational r2(77, 17);
std::cout << "Rational = " << r1 << std::endl; std::cout << "Rational = " << r1 << std::endl;
std::cout << "Call may also be chained due to the signature of the function: " << r1 std::cout << "Call may also be chained due to the signature of the function: " << r1
<< " and " << r2 << std::endl; << " and " << r2 << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Please notice the slightly weird expected syntax for the `operator<<`: the `std::ostream` appears actually twice; the reason for that is to enable chained calls: Please notice the slightly weird expected syntax for the `operator<<`: the `std::ostream` appears actually twice; the reason for that is to enable chained calls:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` C++17 ``` C++17
// Doesn't run on Xeus-cling! // Doesn't run on Xeus-cling!
int main() int main()
{ {
Rational r1(22, 7); Rational r1(22, 7);
Rational r2(84, 9); Rational r2(84, 9);
std::cout << "Rationals = " << r1 << " and " << r2 << std::endl; std::cout << "Rationals = " << r1 << " and " << r2 << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Operator >> ## Operator >>
Operator>> might be overloaded in a similar way; it might be used for instance to create an object from data readin a file. As usual with `operator>>`, you should be cautious and handle well the case in which the flux becomes invalid: Operator>> might be overloaded in a similar way; it might be used for instance to create an object from data readin a file. As usual with `operator>>`, you should be cautious and handle well the case in which the flux becomes invalid:
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` C++17 ``` C++17
// Doesn't run on Xeus-cling due to definition of an operator outside of a class // Doesn't run on Xeus-cling due to definition of an operator outside of a class
// A ticket has been opened for this: https://github.com/QuantStack/xeus-cling/issues/214 // A ticket has been opened for this: https://github.com/QuantStack/xeus-cling/issues/214
#include <iostream> #include <iostream>
class Rational class Rational
{ {
public : public :
explicit Rational(int numerator, int denominator); explicit Rational(int numerator, int denominator);
void Print(std::ostream& out) const; void Print(std::ostream& out) const;
friend std::istream& operator>>(std::istream& in, Rational& r); friend std::istream& operator>>(std::istream& in, Rational& r);
private: private:
//! Set method to modify numerator and denominator. I made the arbitrary choice to make it private //! Set method to modify numerator and denominator. I made the arbitrary choice to make it private
//! to illustrate friendship. //! to illustrate friendship.
void Set(int numerator, int denominator); void Set(int numerator, int denominator);
private : private :
int numerator_ = 0; int numerator_ = 0;
int denominator_ = 0; int denominator_ = 0;
}; };
Rational::Rational(int numerator, int denominator) Rational::Rational(int numerator, int denominator)
: numerator_(numerator), : numerator_(numerator),
denominator_(denominator) denominator_(denominator)
{ } { }
void Rational::Print(std::ostream& out) const void Rational::Print(std::ostream& out) const
{ {
out << numerator_ << " / " << denominator_; out << numerator_ << " / " << denominator_;
} }
std::ostream& operator<<(std::ostream& out, const Rational& r) std::ostream& operator<<(std::ostream& out, const Rational& r)
{ {
r.Print(out); r.Print(out);
return out; return out;
} }
void Rational::Set(int numerator, int denominator) void Rational::Set(int numerator, int denominator)
{ {
numerator_ = numerator; numerator_ = numerator;
denominator_ = denominator; denominator_ = denominator;
} }
std::istream& operator>>(std::istream& in, Rational& r) std::istream& operator>>(std::istream& in, Rational& r)
{ {
int numerator {}, denominator {}; int numerator {}, denominator {};
in >> numerator; in >> numerator;
in >> denominator; in >> denominator;
if (!in) if (!in)
{ {
// If istream is bad; do not modify 'r' // If istream is bad; do not modify 'r'
return in; return in;
} }
r.Set(numerator, denominator); // ok due to friendship! r.Set(numerator, denominator); // ok due to friendship!
return in; return in;
} }
int main() int main()
{ {
Rational r1(22, 7); Rational r1(22, 7);
Rational r2(77, 17); Rational r2(77, 17);
std::cout << "Rational = " << r1 << std::endl; std::cout << "Rational = " << r1 << std::endl;
std::cout << "Call may also be chained due to the signature of the function: " << r1 << " and " << r2 << std::endl; std::cout << "Call may also be chained due to the signature of the function: " << r1 << " and " << r2 << std::endl;
std::cout << "Enter a rational by separating calls by a space" << std::endl; std::cout << "Enter a rational by separating calls by a space" << std::endl;
std::cin >> r1; std::cin >> r1;
if (std::cin) if (std::cin)
std::cout << "Value read is " << r1 << std::endl; std::cout << "Value read is " << r1 << std::endl;
else else
std::cout << "Invalid input!" << std::endl; std::cout << "Invalid input!" << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
This code doesn't run neither in Xeus-cling (due to the operator bug) nor in [Coliru](https://coliru.stacked-crooked.com/) or [Wandbox](https://wandbox.org/) (due to limited `std::cin` support) but you may check it on a local installation. This code doesn't run neither in Xeus-cling (due to the operator bug) nor in [Coliru](https://coliru.stacked-crooked.com/) or [Wandbox](https://wandbox.org/) (due to limited `std::cin` support) but you may check it on a local installation.
Even then, it is not perfect: it handles correctly the case gibberish is given through `std::cin`, but if you put more than two blocks separated by spaces the first two ones are used and the others aren't dealt with... As I said, proper and complete handling of input stream is though! Even then, it is not perfect: it handles correctly the case gibberish is given through `std::cin`, but if you put more than two blocks separated by spaces the first two ones are used and the others aren't dealt with... As I said, proper and complete handling of input stream is though!
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
© _CNRS 2016_ - _Inria 2018-2021_ © _CNRS 2016_ - _Inria 2018-2021_
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_ _This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_ _The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment