14. hét: Concepts
Czirkos Zoltán · 2022.06.21.
Racionális szám
A racionális szám két egész szám hányadosa. Egész számból viszont többféle is van:
short
, int
, long long
– eldönthetjük, mennyi
memóriát szánunk egy szám tárolására, és ettől függ a legnagyobb ábrázolható szám.
Még akár egy saját típust is definiálhatunk. Pl. BigInt<512>
, ha
sablonparaméterrel szeretnénk megadni a bitek számát. Vagy simán BigInt
,
ha dinamikusan változhat.
Írj az első előadás törtes feladatához hasonló osztályt, aminek sablonparamétere, milyen típusú változóval tárolja a számlálót és a nevezőt!
Definiáld az osztályhoz és a hozzá tartozó függvényekhez a concept-eket, add meg, mi a feltétele annak, hogy egy típussal a racionális szám osztály példányosítható legyen!
Írj saját egész szám típust, és példányosítsd vele a törtet! Ellenőrizd
static_assert
-tel, hogy a típusod teljesíti-e az elvárásokat!
Megoldás
Egy lehetésges megoldás (ez a saját típust nem tartalmazza):
#include <type_traits>
#include <iostream>
template <typename T>
concept bool Integral() {
return std::is_integral<T>::value;
}
template <typename T>
concept bool Serializable() {
return requires (std::ostream & os, std::istream & is, T obj) {
{ os << obj } -> std::ostream &;
{ is >> obj } -> std::istream &;
};
}
template <Integral INT>
class Rational {
public:
Rational(INT num, INT den) {}
INT num() const { return num_; }
INT den() const { return den_; }
private:
INT num_;
INT den_;
};
template <typename INT>
requires Serializable<INT>()
std::ostream & operator<<(std::ostream &os, Rational<INT> const & r) {
os << r.num() << '/' << r.den();
return os;
}
template <typename INT>
requires Serializable<INT>()
std::istream & operator>>(std::istream &is, Rational<INT> const & r) {
return is;
}
int main() {
Rational<int> r(2, 3);
std::cout << r;
std::cin >> r;
}