PairArr::operator=(PairArr(ValArrInt(ytemp, NY),ValArrInt(btemp,NY))); - c++

template <typename T1,typename T2>
class Pair
{
private:
T1 a;
T2 b;
public:
T1 & first() { return a; }
T2 & second() { return b; }
T1 first() const { return a; }
T2 second() const { return b; }
Pair(const T1 & aval, const T2 & bval) : a(aval), b(aval) {};
Pair() {}
};
using ValArrInt = std::valarray<int>;
using PairArr = Pair<ValArrInt, ValArrInt>;
class Wine : private string, private PairArr
{
private:
int NY;
public:
Wine(const char * l, int y, const int yr[], const int bot[]);
void Show() const;
};
Wine::Wine(const char * l, int y, const int yr[], const int bot[])
:string(l), NY(y)
{
PairArr::operator=(PairArr(ValArrInt(yr, NY), ValArrInt(bot, NY)));
}
void Wine::Show() const
{
cout << "Wine: " << (const string &)*this << endl;
cout << "\tYear\tBottles\n";
for (int i = 0; i < NY; i++)
{
cout << "\t" << PairArr::first()[i] << "\t"
<< PairArr::second()[i] << endl;
}
}
In this line:
PairArr::operator=(PairArr(ValArrInt(yr, NY), ValArrInt(bot, NY)));
Why does the PairArr component end up with ValArrInt(yr, NY) (the first argument) being both its a, and b members.
Tested with this:
const int YRS = 3;
int y[YRS] = { 1993,1995,1998 };
int b[YRS] = { 48,60,72 };
Wine more("Gushing Grap Red", YRS, y, b);
more.Show();
off-topic:
Keeps asking me to add more details for the amount of code... But no.
Is there some sort of ratio of code to non-code I'm supposed to meet?

So, apparently you have a misprint, you typed aval in both places:
Pair(const T1 & aval, const T2 & bval) : a(aval), b(aval) {};

Related

no instance of overloaded function "search" matches the argument list

I have the following problem with my search function.
It expects 3 parameters, and one of them is something like const rational_t* v. I want to pass a vector through that parameter but it doesnt seems to work..
Code:
#include <iostream>
#include <cmath>
#include <vector>
#include "rational_t.hpp"
using namespace std;
bool search(const rational_t* v, const int n, const rational_t& x)
{
for(int i = 0; i < n; i++) {
if(v[i].value() == x.value()) {
return true;
} else {
return false;
}
}
};
int main()
{
rational_t a(1, 2), b(3), c, d(1, 2);
vector<rational_t> v;
v.push_back(a);
v.push_back(b);
v.push_back(c);
cout << "a.value()= " << a.value() << endl;
cout << "b.value()= " << b.value() << endl;
cout << "c.value()= " << c.value() << endl;
cout << search(v, v.size(), d); // Problem here
return 0;
}
I´ve also tried cout << search(v&, v.size(), d); with the reference &.
Any ideas? Thank You.
The class :
#pragma once
#include <iostream>
#include <cassert>
#include <cmath>
#define EPSILON 1e-6
using namespace std;
class rational_t
{
int num_, den_;
public:
rational_t(const int = 0, const int = 1);
~rational_t() {}
int get_num() const
{
return num_;
}
int get_den() const
{
return den_;
}
void set_num(const int n)
{
num_ = n;
}
void set_den(const int d)
{
assert(d != 0), den_ = d;
}
double value(void) const;
rational_t opposite(void) const;
rational_t reciprocal(void) const;
bool equal(const rational_t &r, const double precision = EPSILON) const;
bool greater(const rational_t &r, const double precision = EPSILON)
const;
bool less(const rational_t &r, const double precision = EPSILON) const;
bool cero_equal(const double precision) const;
void write(ostream &os = cout) const;
void read(istream &is = cin);
};
The first argument of search should be a rational_t* but you're passing a vector<rational_t>.
You want
search(v.data(), v.size(), d)
instead of
search(v, v.size(), d)
But I'd write this like this which is cleaner IMO:
bool search(vector<rational_t> & v, const rational_t& x)
{
for (int i = 0; i < v.size(); i++) {
if (v[i].value() == x.value()) {
return true;
}
else {
return false;
}
}
}
...
cout << search(v, d);

nullptr can't use in valarray

Why can't use nullptr in the constructor function?( the function name: Wine) When i try to do this, the program will break down and no any error report maybe because i don't the reason for that.
#ifndef WINE_H_
#define WINE_H_
#include<iostream>
#include<string>
#include<valarray>
using std::string;
using std::valarray;
template<typename T1, typename T2>
class Pair //member of the wine
{
private:
T1 a;
T2 b;
public:
T1 & first(){ return a; }
T2 & second(){ return b; }
T1 first()const{ return a; }
T2 second()const{ return b; }
Pair(const T1 & aval, const T2 & bval) :a(aval), b(bval){}
Pair(){}
};
typedef valarray<int>ArrayInt;
typedef Pair<ArrayInt, ArrayInt>PairArray;
class Wine
{
private:
string name;
PairArray bt;
int years;
public:
Wine();
Wine(const char * a, int y,int b[], int c[]); //no problem
Wine(const char * a, int y); //here is that problem function
void GetBottles(); //no problem
void Show()const; //no problem
int Sum(){ return bt.second().sum(); }
};
Wine::Wine(const char * a, int y) :name(a), years(y), bt(ArrayInt(0, y), ArrayInt(0, y)){}
**//When I am trying to use nullptr to instead 0 in the ArrayInt(0,y),the whole program will break down during work.**
Wine::Wine(const char * a, int y, int b[], int c[]) :bt(ArrayInt(b, y), ArrayInt(c, y))
{
name = a;
years = y;
}
Wine::Wine() :bt(ArrayInt(),ArrayInt())
{
name = "null";
years = 0;
}
void Wine::GetBottles()
{
std::cout << "Please input the years and the bottles\n";
for (int i = 0; i < years; i++)
{
std::cout << "input the year: ";
(std::cin >> bt.first()[i]).get();
std::cout << "input the bottles";
(std::cin >> bt.second()[i]).get();
}
}
void Wine::Show()const
{
using std::cout;
using std::endl;
for (int i = 0; i < years; i++)
{
cout << bt.first()[i] << '\0' << bt.second()[i] << endl;
}
}
#endif
#include<iostream> //test part
#include"wine.h"
int main(void)
{
using std::cin;
using std::cout;
using std::endl;
cout << "Enter name of wine: ";
char lab[50];
cin.getline(lab, 50);
cout << "Enter number of years: ";
int yrs;
cin >> yrs;
Wine holding(lab, yrs);
holding.GetBottles();
holding.Show();
return 0;
}
Thank your for your help!
This is a funny one. The reason why it breaks in one example, but not another is following:
There are two different constructors for std::valarray (more than that, but those two matter):
valarray( const T& val, std::size_t count ); // 1
valarray( const T* vals, std::size_t count ); // 2
When you use 0 (valarray(0, y)) you are calling the first version - creating an array of y elements, where every element is initialized to 0.
But when you are calling it with nullptr, you are calling the second version of it - trying to initialize your new array with a copy from an array pointed to by the first argument to the constructor. But your first argument is nullptr, and any attempt to use at as an array triggers undefined behavior, and program crashes.

Program to construct house with bricks with 3 dimensional vector

I have 2 classes : 1 brick and 1 construction class, I must built a house or an object with bricks, each construction can take a brick as an argument, it has also operators + , - and ^ , and +=, -= , ^= , that add a construction on the right of the construction, "behind" (in the depth and 1 level above a construction...
I have to do this with the appropriate according indices of my 3 dimensional vector....
The problem is: Everything compiles fine, but my program crashes when I start this... I spent a whole day on this program and I dont know where my error is...
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Pour simplifier
typedef string Forme ;
typedef string Couleur ;
class Brique
{
private:
Forme forme ;
Couleur couleur ;
public:
/*****************************************************
Compléter le code à partir d'ici
*******************************************************/
Brique( Forme f, Couleur c ) : forme(f),couleur(c) {};
ostream& afficher(ostream& sortie) const ;
Forme getForme() const {return forme;};
Couleur getCouleur() const {return couleur;};
};
ostream& Brique::afficher(ostream & sortie) const {
if (this->getCouleur() != "") {
return sortie<<"("<<this->getForme()<<", "<<this->getCouleur()<<")";
}
else {
return sortie<<this->getForme();
}
};
ostream& operator<<(ostream& sortie, Brique const& z) {
return z.afficher(sortie);
};
class Construction
{
friend class Grader;
public:
vector<vector<vector<Brique> > > contenu;
public:
Construction(Brique b) : contenu(1, vector<vector<Brique> >(1, vector<Brique>(1,b))) {};
//Construction(Construction c) ;
ostream& afficher(ostream& sortie) const ;
Construction& operator^=(Construction const & z) ;
Construction& operator-=(Construction const & z) ;
Construction& operator+=(Construction const & z) ;
};
ostream& Construction::afficher(ostream& sortie) const {
size_t i(contenu.size());
for (size_t j = 0; j< i; j++) {
cout<<"Couche "<<j<<" :"<<endl;
for (size_t k = 0; k<contenu[j].size() ; k++) {
for (size_t t = 0; t< contenu[j][k].size(); t++) {
cout <<contenu[j][k][t];
}
}
}
return cout;
};
ostream& operator<<(ostream& o, Construction const& z) {
return z.afficher(o);
};
Construction& Construction::operator^=(Construction const & z) {
//int i(this->contenu.size());
//int j(this->contenu[i].size());
//int k(this->contenu[i][j].size());
int m(z.contenu.size());
//int n(z.contenu[m].size());
//int p(z.contenu[m][n].size());
this->contenu.push_back(z.contenu[m]);
return *this;
};
Construction& operator^(Construction & o, Construction & z) {
//o.contenu.push_back(z.contenu[z.contenu.size()]);
o^= z;
return o;
}
Construction& Construction::operator+=(Construction const & z) {
int i(this->contenu.size());
int j(this->contenu[i].size());
//int k(this->contenu[i][j].size());
int m(z.contenu.size());
int n(z.contenu[m].size());
//int p(z.contenu[m][n].size());
if ( n < j) { return *this;}
else if ( n > j) {
int a(0);
for (auto element : z.contenu[m][n]) {
this->contenu[i][j].push_back(element);
++a;
if (a == n) { return * this;}
}
}
else {
this->contenu[i].push_back(z.contenu[m][n]);
}
return *this;
}
Construction operator+(Construction t, Construction z) {
return t+=z;
}
Construction& Construction::operator-=(Construction const & z) {
int i(this->contenu.size());
int j(this->contenu[i].size());
int k(this->contenu[i][j].size());
int m(z.contenu.size());
int n(z.contenu[m].size());
int p(z.contenu[m][n].size());
if ( p < k) { return *this;}
else {
this->contenu[i][j].push_back(z.contenu[m][n][p]);
}
return *this;
}
Construction& operator-(Construction & o, Construction const & z) {
/*
int i(o.contenu.size());
int m(z.contenu.size());
int n(z.contenu[m].size());
int p(z.contenu[m][n].size());
o.contenu[i][m].push_back(z.contenu[m][n][p]);
*/
return o-=z;
}
const Construction operator*(unsigned int n, Construction const& a)
{
Construction b = a;
for (unsigned int i=1;i<n;i++) {
b.operator+=(a);
}
return b;
};
const Construction operator/(unsigned int n, Construction const& a)
{
Construction b=a;
for (unsigned int i=1;i<n;i++) {
b^=a;
}
return b;
};
const Construction operator%(unsigned int n, Construction const& a)
{
Construction b=a;
for (unsigned int i=1;i<n;i++) {
b-=a;
}
return b;
};
/*******************************************
* Ne rien modifier après cette ligne.
*******************************************/
int main()
{
// Modèles de briques
Brique toitD("obliqueD", "rouge");
Brique toitG("obliqueG", "rouge");
Brique toitM(" pleine ", "rouge");
Brique mur (" pleine ", "blanc");
Brique vide (" ", "");
unsigned int largeur(4);
unsigned int profondeur(3);
unsigned int hauteur(3); // sans le toit
// on construit les murs
Construction maison( hauteur / ( profondeur % (largeur * mur) ) );
cout<<maison;
// on construit le toit
Construction toit(profondeur % ( toitG + 2*toitM + toitD ));
toit ^= profondeur % (vide + toitG + toitD);
// on pose le toit sur les murs
maison ^= toit;
// on admire notre construction
cout << maison << endl;
return 0;
}
anybody got an Idea why my program crashes?

How can I make different constructors for different temperature units in C++?

So you should be able to input temperature in C, K or F, which will call a different constructor for each of them. How do those constructors differ?
Assuming you're using C++11, you could use user-defined literals to express that a number is in Fahrenheit, Kelvin or Celcius.
If you're not using C++11, you can always have an enum type parameter to your constructor that expresses this. The user-defined literal approach is probably much better though.
If you use the dedicated datatypes for the value of temperature, like:
struct Celsius { double value; }
struct Kelvin { double value; }
struct Farahemsomething { double value; }
then you can just use simple overloads:
class MyClass
{
public:
MyClass(Celsius temp) { .... = temp.value; ... }
MyClass(Kelvin temp) { .... = temp.value; ... }
...
}
However, if you everywhere use just double for all values, then you will have to differentiate the constructors with something else. Enums may be quite useful, but you will have it in the same constructor and have to switch over the enum value:
enum TemperatureUnits
{ Celsius,Kelvin, Farahemsomething };
class MyClass
{
public:
MyClass(TemperatureUnits unit, double value) {
if(unit == Celsius)
{ ... }
else if(unit == ....
...
...
}
}
You can also mix "hollow types" with raw double to artificially enable the use of overloads, but it gets tricky:
struct Celsius { }
struct Kelvin { }
struct Farahemsomething { }
class MyClass
{
public:
MyClass(Celsius unit, double value) { .... = value; ... }
MyClass(Kelvin unit, double value) { .... = value; ... }
...
}
Here, note that "unit" is just an empty struct that allows you to pick correct overload, so you invoke the constructor with simple empty "Celsius" followed by 234.55 value.
EDIT: and yet again I forgot about C11 features.. AnotherTest's suggestion about custom literals is probably the easiest.
I know I'm a little late with this, but here is what I came up with:
#include <iostream>
namespace units {
template<int> struct temp_unit { };
typedef temp_unit<1> celcius;
typedef temp_unit<2> fahrenheit;
typedef temp_unit<3> kelvin;
typedef temp_unit<4> reaumur;
typedef temp_unit<5> rankine;
}
namespace priv {
struct converter_impl {
virtual ~converter_impl() { }
virtual float to_celcius() const = 0;
virtual float to_fahrenheit() const = 0;
virtual float to_kelvin() const = 0;
virtual float to_reaumur() const = 0;
virtual float to_rankine() const = 0;
};
struct from_celcius : converter_impl {
protected:
float m_value;
public:
from_celcius(float v) : m_value(v) { }
float to_celcius() const { return m_value; }
float to_fahrenheit() const { return (m_value * 1.8) + 32; }
float to_kelvin() const { return (m_value + 273.15); }
float to_reaumur() const { return (m_value * 0.8); }
float to_rankine() const { return (m_value * 1.8 +32 + 459.67); }
};
struct from_fahrenheit : converter_impl {
protected:
float m_value;
public:
from_fahrenheit(float v) : m_value(v) { }
float to_celcius() const { return ((m_value - 32) / 1.8); }
float to_fahrenheit() const { return m_value; }
float to_kelvin() const { return ((m_value + 459.67) / 1.8); }
float to_reaumur() const { return ((m_value - 32) / 2.25); }
float to_rankine() const { return (m_value + 459.67); }
};
struct from_kelvin : converter_impl {
protected:
float m_value;
public:
from_kelvin(float v) : m_value(v) { }
float to_celcius() const { return (m_value - 273.15); }
float to_fahrenheit() const { return ((m_value * 1.8) - 459.67); }
float to_kelvin() const { return m_value; }
float to_reaumur() const { return ((m_value - 273.15) * 0.8); }
float to_rankine() const { return (m_value * 1.8); }
};
struct from_reaumur : converter_impl {
protected:
float m_value;
public:
from_reaumur(float v) : m_value(v) { }
float to_celcius() const { return (m_value * 1.25); }
float to_fahrenheit() const { return ((m_value * 2.25) + 32); }
float to_kelvin() const { return ((m_value * 1.25) + 273.15); }
float to_reaumur() const { return m_value; }
float to_rankine() const { return ((m_value * 2.25) + 32 + 459.67); }
};
struct from_rankine : converter_impl {
protected:
float m_value;
public:
from_rankine(float v) : m_value(v) { }
float to_celcius() const { return ((m_value - 32 - 459.67) / 1.8); }
float to_fahrenheit() const { return (m_value - 459.67); }
float to_kelvin() const { return (m_value / 1.8); }
float to_reaumur() const { return ((m_value - 32 - 459.67) / 2.25); }
float to_rankine() const { return m_value; }
};
}
struct temp_converter {
protected:
priv::converter_impl * m_impl;
public:
temp_converter(float value, units::celcius) : m_impl(new priv::from_celcius(value)) { }
temp_converter(float value, units::fahrenheit) : m_impl(new priv::from_fahrenheit(value)) { }
temp_converter(float value, units::kelvin) : m_impl(new priv::from_kelvin(value)) { }
temp_converter(float value, units::reaumur) : m_impl(new priv::from_reaumur(value)) { }
temp_converter(float value, units::rankine) : m_impl(new priv::from_rankine(value)) { }
~temp_converter() { delete m_impl; }
float to_celcius() const { return m_impl->to_celcius(); }
float to_fahrenheit() const { return m_impl->to_fahrenheit(); }
float to_kelvin() const { return m_impl->to_kelvin(); }
float to_reaumur() const { return m_impl->to_reaumur(); }
float to_rankine() const { return m_impl->to_rankine(); }
inline float as(units::celcius) const { return to_celcius(); }
inline float as(units::fahrenheit) const { return to_fahrenheit(); }
inline float as(units::kelvin) const { return to_kelvin(); }
inline float as(units::reaumur) const { return to_reaumur(); }
inline float as(units::rankine) const { return to_rankine(); }
};
int main(int argc, char ** argv) {
temp_converter tc(-31, units::reaumur());
std::cout << "Celcius: " << tc.to_celcius() << std::endl;
std::cout << "Fahrenheit: " << tc.to_fahrenheit() << std::endl;
std::cout << "Kelvin: " << tc.to_kelvin() << std::endl;
std::cout << "Réaumur: " << tc.to_reaumur() << std::endl;
std::cout << "Rankine: " << tc.to_rankine() << std::endl;
return 0;
}
I know you only asked how to differentiate between units, but I got carried away while coding an example.
There are many ways you can achieve this, you can specify the unit using an enum in the constructor parameter - a solution with a single constructor. In this case you will be passing a primitive number and the enum defines how its value is interpreted.
If you really need different constructors you can specify your own Celsius, Fahrenheit and Kelvin types and pass those to different constructors.
struct Fahrenheit {
Fahrenheit (double d = 0) : t(d) {}
double t;
};
struct Celsius {
Celsius(double d = 0) : t(d) {}
double t;
};
struct Kelvin {
Kelvin(double d = 0) : t(d) {}
double t;
};
class Temperature {
public:
Temperature(Fahrenheit f) {
temperature.t = (f.t + 459.67) * 5 / 9;
cout << "Fahrenheit constructor" << endl;
}
Temperature(Celsius c) {
temperature.t = c.t + 273.15;
cout << "Celsius constructor" << endl;
}
Temperature(Kelvin k) : temperature(k) {
cout << "Kelvin constructor" << endl;
}
double getTemperature() {
return temperature.t;
}
private:
Kelvin temperature;
};
And in main:
Temperature t1(Kelvin(50)), t2(Fahrenheit (90)), t3(Celsius(23));
cout << t1.getTemperature() << " " << t2.getTemperature() << " " << t3.getTemperature() << endl;
The output:
Kelvin constructor
Fahrenheit constructor
Celsius constructor
50 305.372 296.15
The class will store temperature internally as Kelvin (most scientific IMO) and will convert other units to Kelvin.

C++ valarray/template classes not working

this is my first post here but I've been a frequent reader of various topics here.
Now I'm stuck with a programming issue with c++, its basically a template class called "Pair" which should contain 2 valarrays of ints and then be included in another class called Wine. Problem is I'm not getting either the constructors right or the header file according to my compiler!
Take a look and please try to help me, the main issue is that it the valarrays wont take ints as arguments + i dont understand how i can convert a usual int array to a valarray with just 1 constructor argument:
#ifndef Derp
#define Derp
#include <valarray>
template <typename T1, typename T2>
class Pair
{
private:
T1 a;
T2 b;
public:
T1 & first();
T2 & second();
T1 first() const {return a;}
T1 second() const {return b;}
Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) {}
Pair() {}
};
template Pair<std::valarray<int>, std::valarray<int> >;
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine
{
private:
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
std::string name;
int years;
PairArray arr;
public:
Wine(const char * l, int y, const int yr[], const int bot[]);
Wine(const char * l, int y);
void GetBottles();
std::string Label();
int sum();
void show();
};
#endif
So, heres the header file, now comes the first .cpp file with all the function - definitions:
#include <iostream>
#include <valarray>
#include <cstring>
#include "K14O1.h"
template <typename T1, typename T2>
T1 & Pair<T1, T2>::first()
{
return a;
}
template <typename T1, typename T2>
T2 & Pair<T1, T2>::second()
{
return b;
}
Wine::Wine(const char * l, int y, const int yr[], const int bot[])
: arr(y, y)
{
name = l;
years = y;
for(int a = 0; a < y; a++)
{
arr.first()[a] = yr[a];
arr.second()[a] = bot[a];
}
}
Wine::Wine(const char * l, int y)
: arr()
{
name = l;
years = y;
arr.first() = y;
arr.second() = y;
}
void Wine::GetBottles()
{
for(int c = 0; c < years; c++)
{
std::cout << "Skriv in antal buteljer för det året: ";
std::cin >> arr.first()[c];
std::cout << "Skriv in årgång: ";
std::cin >> arr.second()[c];
}
}
std::string Wine::Label()
{
return name;
}
typedef std::valarray<int> ArrayInt;
int Wine::sum()
{
int b;
int ar = 0;
while(arr.second()[b])
{
ar += arr.second()[b];
b++;
};
return ar;
}
void Wine::show()
{
std::cout << "Vin: " << name << std::endl;
int b = 0;
while(arr.first()[b])
{
std::cout << arr.first()[b] << "\t" << arr.second()[b] << std::endl;
b++;
};
}
Finally the last .cpp file:
#include <iostream>
#include <valarray>
#include "K14O1.h"
using namespace std;
int main(int argc, char * argv[])
{
const int YRS = 3;
int y[YRS] = {1993, 1995, 1998};
int b[YRS] = {48, 60, 72};
Wine more("Gushing Grape Red", YRS, y, b);
cout << "Skriv in vinets namn: ";
char lab[50];
cin.getline(lab, 50);
cout << "Skriv in antal årgångar: ";
int yrs;
cin >> yrs;
Wine holding(lab, yrs);
holding.GetBottles();
holding.show();
more.show();
cout << "Totalt antal buteljer av " << more.Label()
<< ": " << more.sum() << endl;
cout << "HEJDASADAN" << endl;
return 0;
}
I would be enourmosly grateful if you guys could tell me whats wrong and how to fix it. Im currently doing stephen pratas C++ book and this is a exercise, thanks!
Any other general tips on coding would be wonderful aswell, have a good time!
What's wrong: Well, honestly, where do I start?
Firstly, there is a std::pair structure. Secondly, the valarray stuff was a total mistake and not at all used anymore. Thirdly, const char*, int[] arguments? Owch. Can you say buffer overrun and memory corruption? Fourthly,
int Wine::sum()
{
int b;
int ar = 0;
while(arr.second()[b])
{
ar += arr.second()[b];
b++;
}
return ar;
}
You didn't initialize b. Undefined behaviour.
The Definitive C++ Book Guide and List
This question lists good C++ books, and Stephen Prata is mentioned as having a very bad book. This code sample supports that. Burn your book and buy one that doesn't suck, would be my recommendation.