My swap program is not working using Template? - c++

I'm using Template keyword to run simple swap program, Kindly help me why my program is not working out?
#include<iostream>
using namespace std;
template<typename T>
void Swap(T m, T n)
{
T temp;
temp = m;
m = n;
n = temp;
}
int main()
{
int i = 5, j = 6;
cout << "Before swapping:" << endl;
cout << i << " and " << j << endl;
Swap(i, j);
cout << "After Swapping:" << endl;
cout << i << " and " << j << endl;
return 0;
}
Output:

You are creating copies of your arguments because you are taking them by value. If you want to update them within the function you should take them by reference:
void Swap(T& m, T& n)
// ^ ^
Additionally, your implementation has an implicit constraint that T must be default-constructible, which is not necessary for swapping. You should construct your temp variable directly:
T temp = m;
You'd also be better off using move semantics to avoid making copies:
T temp(std::move(m)); // or T temp = std::move(m);
m = std::move(n);
n = std::move(temp);

Related

Getting segmentation fault (core dumped) error when declaring a int variable

I was trying to create vector like class. Here is my code
#include <bits/stdc++.h>
using namespace std;
template<class t>
class vec{
t *start;
int size=0;
public:
void add_value(t a){
*(start+(sizeof(t)*size)) = a;
cout << (start+(sizeof(t)*size))<< " = "<< *(start+(sizeof(t)*size))<<endl;
size++;
// cout << start<< endl;
}
void operator [](int i){
cout << (start+(sizeof(t)*i))<< " = "<< *(start+(sizeof(t)*i))<<endl;
}
int length(){
return size;
}
};
int main(){
vec<int> t;
cout << t.length()<<endl;
t.add_value(8);
t.add_value(10);
cout << t.length()<<endl;
t[1];
}
This gives me correct output.
0
0x7fff0fe9b5d0 = 8
0x7fff0fe9b5e0 = 10
2
0x7fff0fe9b5e0 = 10
But when declare a int variable in main function like.
int main(){
int i=0; //newline
vec<int> t;
cout << t.length()<<endl;
t.add_value(8);
t.add_value(10);
cout << t.length()<<endl;
t[1];
}
output.
0
Segmentation fault (core dumped)
I also tried printing address of start variable and new int variable int those are different.
You probably want something like this:
#include <iostream>
using namespace std;
template<class t>
class vec {
t* start = new t[100]; // initialize the pointer (fixed size of 100, to be improved)
int size = 0;
public:
void add_value(t a) {
*(start + size) = a;
size++;
}
t operator [](int i) { // should return a t instead of a void
return *(start + i);
}
int length() {
return size;
}
};
int main() {
vec<int> t;
cout << "t.length() = " << t.length() << endl;
t.add_value(8);
t.add_value(10);
cout << "t.length() = " << t.length() << endl;
// display all values in t
for (int i = 0; i < t.length(); i++)
{
cout << "t[" << i << "] = " << t[i] << endl;
}
}
All multiplication by sizeof(t) have been removed, because pointer arithmetic already does this for you.
This very poor and minimalist example works as you expect, but the maximum number of elements you can store in the class is 100. I leave the improvement as an exercise to you.
BTW there are many other improvements you need to do, especially you need a destructor and possibly the rule of three
Note:
You should replace all instances of *(start + x) with start[x] which does exactly the same thing but which is more idiomatic and more readable.

How does template in c ++ actually work in background?

**
why the output of code is
x = 1 count = 0
x = 1 count = 1
x = 1.1 count = 0
**
//code for template
#include <iostream>
using namespace std;
template <typename T>
void fun(const T&x)
{
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
int main()
{
fun<int> (1);//for int
cout << endl;
fun<int>(1);//for int
cout << endl;
fun<double>(1.1);//for int
cout << endl;
return 0;
}
Is Compiler creates a new instance of a template function for every data type in c++ in above code and also how can we assign rvalue to reference variable while calling function fun() ?
In your code, you have used the stencil to create two functions, one function uses the int type, the other function uses the double type:
void fun(const int &x)
{
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
void fun(const double &x)
{
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
The compiler can recognize the second fun<int>(1) as a call to the above integer function, thus not needing to generate a third function.
Passing by reference or const reference is the same with template functions as it is with normal functions; the template only affects the data type, not how parameters are passed.

C++ cout inside loop for printing vector of vectors fails

template<typename s>
void vecprint2d(const s& vec){
cout<<"{"<<endl;
for(int x = 0; x < vec.size(); x++){
cout<<"{";
for(int y = 0; y < vec[x].size() - 1;y++){
cout << vec[x][y]<<", ";
}
cout<<vec[x][vec[x].size() - 1]<<"}"<<endl;
}
cout<<"}"<<endl;
}
int main(){
vector<vector<int>> vec = {{1,2,3},{},{4,5,6}};
vecprint2d(vec);
return 0;
}
in my attempt at a function for printing a vector of vectors,
why does cout inside the inner loop cause problems, or is the problem elsewhere?
the output right now looks like:
{
{
If the inner vector's size is 0, size() - 1 will overflow and it will loop forever and/or crash. Could that be what is happening on your raspberry pi?
To avoid this, handle 0-sized vectors as well.
For example like this:
template<typename s>
void vecprint2d(const s& vec) {
cout << "{" << endl;
for (auto const& row : vec) {
cout << "{";
int i = 0;
for (auto const& val : row) {
if (i++)
cout << ", ";
cout << val;
}
cout << "}" << endl;
}
cout << "}" << endl;
}
The size() function of an empty vector will return an (unsigned) value of zero and, in your inner loop, you test y against vec[x].size() - 1. This will give a value that has 'underflowed' and thus have the maximum value that a size_t variable can hold, so the y loop will run a very large number of times! However, it will likely fail on the first loop, because trying to access any element of an empty vector is undefined behaviour.
To fix this, enclose your inner loop in an "is it empty" if block (in fact, you should do this for both loops). Here's a possible solution:
template<typename s>
void vecprint2d(const s& vec)
{
cout << "{" << endl;;
if (!vec.empty()) for (size_t x = 0; x < vec.size(); x++) {
cout << "{";
if (!vec[x].empty()) {
for (size_t y = 0; y < vec[x].size() - 1; y++) {
cout << vec[x][y] << ", ";
}
cout << vec[x][vec[x].size() - 1];
}
cout << "}" << endl;
}
cout << "}" << endl;
}
Feel free to ask for further clarification and/or explanation.

print multiple numbers in ascending order in C++

So I'm working on this project where I have to gather 2 integers from a user 3 times (loop), and each time I have to print the two integers in ascending order. The restriction is that you can only have two cout statements within your loop (one is asking for their input and the second is outputting the ascending order).
My only issue with that is, when I think about ascending order, I would do it like (which has two count statements):
if (m<n) {
cout << m << n << endl;
if (m>n){
cout << n << m << endl;
So far, this is what I have:
#include <iostream>
using namespace std;
int main(int,char**) {
int n, m, z;
for (n=0;n<3;n++){
cout << "Give me two numbers: ";
cin >> m;
cin >> z;
//if (m>z);
//cout << m << z << "sorted is: " << m << z << endl;
// This is where I'm getting stuck because I need two count statements to organize in ascending order as shown above
}
}
So have you considered to change which variable holds the lower number? e.g.
if(m > n){
int temp = n;
n = m;
m = temp;
}
Then you can just use one print
cout << m << " " << n << endl;
This is where I'm getting stuck because I need two count[sic]
statements to organize in ascending order as shown above
You have marked this post as C++:
Additional options to consider:
use algorithm lib:
#include <algorithm>
std::cout << std::min(m,n) << " " << std::max(m,n) << std::endl;
or use conditional / ternary operator in your cout:
std::cout << ((m<n) ? m : n) << " " << ((n<m) ? m : n) << std::endl;
References are sometimes fun ... but perhaps this challenge is too trivial.
// guess m < n
int& first = m;
int& second = n;
if(!(m<n)) { first = n; second = m; }
std::cout << first << " " << second << std::endl;
Pointers can do the same:
// guess m < n
int& first = &m;
int& second = &n;
if(!(m<n)) { first = &n; second = &m; }
std::cout << *first << " " << *second << std::endl;
or you can use
lambda expressions, or
c++ functions, or
c++ class methods
But I think each of these would be directly comparable to either of the first alternatives.

Vector iterator not dereferencable (vector inside vector)

I am trying to write some data from these vectors onto text files. When I run the code it returns a run time error. Category, Product, Cart, Customerand Address are all struct with members that each get_member returns.
ofstream write_cats;
write_cats.open("catprd.dat", ios::out, ios::trunc);
vector<Category>::iterator i;
write_cats << cats.size() << endl;
for (i = cats.begin(); i < cats.end(); i++) {
write_cats << i -> get_catid() << '\t';
}
vector<Product>::iterator j;
write_cats << prods.size() << endl;
for (j = prods.begin(); j < prods.end(); j++) {
write_cats << j -> get_prodid() << '\t';
write_cats << j -> get_prodprice() << endl;
}
write_cats.close();
ofstream write_carts;
write_carts.open("carts.dat", ios::out, ios::trunc);
vector<Cart>::iterator k;
write_carts << carts.size() << endl;
for (k = carts.begin(); k < carts.end(); k++) {
write_carts << k -> get_cartid() << '\t';
write_carts << k -> get_day() << endl;
}
vector<Cart_item>::iterator l;
write_carts << cart_items.size() << endl;
for (l = cart_items.begin(); l < cart_items.end(); l++) {
write_carts << l -> get_cartitemid() << '\t';
write_carts << l -> get_qty() << endl;
}
write_carts.close();
ofstream write_custs;
write_custs.open("custs.dat", ios::out, ios::trunc);
vector<Customer>::iterator m;
vector<Address>::iterator n;
write_custs << custs.size() << endl;
for (m = custs.begin(); m < custs.end(); m++) {
write_custs << m -> get_cust_id() << '\t';
write_custs << n -> get_zip_code() << endl;
}
write_custs.close();
Returns run time error "Vector iterator not dereferencable"
Here is how struct Address looks like:
using namespace std;
#pragma once
#include <string>
struct Address {
public:
int get_st_number() const{return st_number;}
int get_zip_code() const{return zip_code;}
string get_st_name() const{return st_name;}
Address(){}
Address (int num, string name, int zip)
: st_number(num), st_name(name), zip_code(zip) {}
private:
int st_number;
int zip_code;
string st_name;
};
and struct Customer:
struct Customer {
public:
Address get_address() const{return addr;}
int get_cust_id() const{return cust_id;} customer id
string get_name() const{return cust_name;}
Customer (int id, string n, Address a)
: cust_id(id), cust_name(n), addr(a) {}
string display_addr() const {
std::cout<<setw(15)<<cust_name<<" ";
std::cout<<setw(15)<<cust_id<<" ";
return string();
}
private:
int cust_id;
string cust_name;
Address addr;
};
you forget to initialize vector<Address>::iterator n;
You are declaring an iterator n, but not initialising it to a dereferencable value. From your update, it looks like you want to print the Address associated with the customer; so you'd access via the customer referred to by m, rather than a separate iterator:
write_custs << m -> get_cust_id() << '\t';
write_custs << m -> get_address().get_zip_code() << endl;
Also, it might be a good idea to scope each iterator inside its loop; that's less error-prone than declaring a new one in the outer scope each time:
for (vector<Whatever>::const_iterator i = stuff.begin(); i != stuff.end(); ++i) {
// do stuff with "i"
}
// "i" is no longer available - no danger of accidentally using it again.
And a couple of other points:
You should use != rather than < to compare with the end() iterator; < doesn't work for some types of iterator;
You should write a new-line to the file as '\n' rather than endl; endl flushes the file buffer, forcing the file to be written to disk at that point, which can be extremely slow.