how to define a friend template function of a template class - friend-function

I've a Template Class array_T which is a general purpose array and a Template function linear search TEMPLATE.h and its declared as friend for the class arrayTemplate.h so it could be able to use the class's member function getArraySize() and the class's data member a which is a dynamic allocation array
arrayTemplate.h
#ifndef arrayTemplate
#define arrayTemplate
#include"linear search TEMPLATE.h"
#include<iostream>
using namespace std;
template <class T>
class array_T {
private:
T *a;
int arraySize;
public :
friend void linearSearch(array_T object);
array_T(int s) {
arraySize = s;
a = new T[arraySize];
for (int i= 0; i < arraySize; ++i) {
a[i] = 0;
}
}
~array_T() {
delete[]a;
}
void setArray() {
for (int i=0; i < arraySize; ++i) {
cout << "Enter the elements of the array " << endl;
cin >> a[i];
}
}
void getArray() {
for (int i=0; i < arraySize; ++i) {
cout << a[i] << endl;
}
}
int getArraySize() {
return arraySize;
}
};
#endif
linear search TEMPLATE.h
#include"arrayTemplate.h"
#include<iostream>
using namespace std;
template <class T>
//void linearSearch(T desiredData, int arraySize, T *elemnts) {
void linearSearch(array_T<T> object , T desiredData) {
int arraySize = object.getArraySize();
int loc = -1;
int i = 0;
for (i = 0; i < arraySize; ++i) {
if (object.a[i] == desiredData) {
loc = i;
break;
}
}
if (loc > 0) {
cout << "the Item is found at position " << i + 1 << endl;
}
else {
cout << "the item is not found ";
}
}
main.cpp
#include"arrayTemplate.h"
#include"linear search TEMPLATE.h"
#include<iostream>
using namespace std;
int main() {
array_T<int> myArray(7);
myArray.setArray();
linearSearch(myArray,50)
return 0 ;
}
these are the errors i got
linear search template.h(8): error C2065: 'array_T': undeclared
identifier
linear search template.h(8): error C2065: 'object': undeclared
identifier
linear search template.h(8): error C2275: 'T': illegal use of this
type as an expression
linear search template.h(6): note: see declaration of 'T'
linear search template.h(8): error C2146: syntax error: missing ')'
before identifier 'desiredData'
main.cpp(14): error C2660: 'linearSearch': function does not take 2
arguments
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Related

Why does my code giving me "mismatch in formal parameter list"?

I am trying to transfer the elements from a source stack to a destination stack. And for that i am using some variables and making sure that get transfered into the destination stack in the same order as they were in the source stack. I wrote the following code
#include <iostream>
#include <stack>
using namespace std;
template <typename S>
void transferByVar(stack<S> &source, stack<S> &dest)
{
int var = 0;
S topVal;
if (source.empty())
return;
else if (source.size() == 1)
{
dest.push(source.top());
source.pop();
}
int size = source.size();
while (count != size)
{
topVal = source.top();
source.pop();
while (source.size() != count)
{
dest.push(source.top());
source.pop();
}
source.push(topVal);
while (!dest.empty())
{
source.push(dest.top());
dest.pop();
}
++count;
}
}
int main()
{
stack <int> s1;
stack<int> s2;
s1.push(0);
s1.push(1);
s1.push(2);
s1.push(3);
s1.push(4);
s1.push(5);
s1.push(6);
s1.push(7);
s1.push(8);
s1.push(9);
transferByVar(s1, s2);
int size = s2.size();
for (int i = 0; i < size; i++)
{
cout << s2.top() << " ";
s2.pop();
}
return 0;
}
but it gives me an error of C2563: mismatch of formal parameter list. What can I do to fix this?

c++ random set seed failed

I am trying to set seed to the c++ std::default_random_engine:
#include<random>
#include<time.h>
#include<iostream>
using namespace std;
void print_rand();
int main() {
for (int i{0}; i < 20; ++i) {
print_rand();
}
return 0;
}
void print_rand() {
default_random_engine e;
e.seed(time(0));
cout << e() << endl;
}
It seems that the printed numbers are same, how could I set the seed to generate the random number according to the time?
You have to seed only once instead of every time the function is called. Then you will get different values. I will move the functionality to main() to demonstrate this.
#include<random>
#include<time.h>
#include<iostream>
int main() {
std::default_random_engine e;
e.seed(time(0));
for (int i{0}; i < 20; ++i) {
std::cout << e() << std::endl;
}
return 0;
}
See Live Demo
As #P.W. said, you should seed only once. A minimal change in that direction would be using a static variable with the seed given to the constructor:
#include<random>
#include<time.h>
#include<iostream>
void print_rand();
int main() {
for (int i{0}; i < 20; ++i) {
print_rand();
}
return 0;
}
void print_rand() {
static std::default_random_engine e(time(0));
cout << e() << endl;
}

C++11 Lambda custom comparator slows down sorting

Custom lambda Comparator slower than normal function c++11. I experienced this a few times. But, Still Couldn't figure out the reason why this is so. Does anyone experience this and know the cause behind it?
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 1;
vector<int> v(N);
vector<int> sorted(N);
map<int, int> counts;
long long start;
void startClock() {
start = clock();
}
void stopClock() {
cout << float( clock () - start ) / CLOCKS_PER_SEC << endl;
}
void copyOriginal() {
for (int i = 0; i < N; ++i)
sorted[i] = v[i];
}
void sortWLambda(map<int, int>& counts) {
cout << "sorting with lambda" << endl;
sort(sorted.begin(), sorted.end(), [counts](const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
});
}
bool comparator(const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
}
void sortWoLambda() {
cout << "sorting w/o lambda" << endl;
sort(sorted.begin(), sorted.end(), comparator);
}
int main() {
for (int i = 0; i < N; ++i) {
int num = rand() % 1234;
counts[num]++;
v[i] = num;
}
copyOriginal();
startClock();
sortWLambda(counts);
stopClock();
copyOriginal();
startClock();
sortWoLambda();
stopClock();
return 0;
}
sorting with lambda 6.28 sec
sorting w/o lambda 0.17 sec
pass by reference made the difference for lambda.
I tried this..
sort(sorted.begin(), sorted.end(), [&counts](const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
});
now this takes same time as normal function
Passing by constant reference in the lambda capture list this helped me too!

how would I go about handling these return type errors? (hashmap/table)

#ifndef HASHMAP_H
#define HASHMAP_H
#include <iostream>
#include <string>
#include <vector>
using namespace std;
enum Status{open , active, deactivated };
//template <typename T>
template</*typename Key,*/ typename T>
class hashmap{
private:
class Node{
public:
const string Key;
//vector<T> values;
T value;
Status status;
Node(string key, T val) :Key(key), value(val), status(active){}
void operator =(const Node &n){
string *ptr;
ptr = (string*)(&(this->Key));
*ptr = n.Key;
//Node(n);
this->status = n.status;
this->value = n.value;
}
Node() :status(open){}
Node(const string& key) :Key(key), status(active){}
//Node(const Node &n) : value(n.val), status(n.status){}
};
//typedef map<
unsigned int hash(const string& s, int tableSize){
unsigned int h = 0;
/*each(s)*/
for(auto it : s) h = 31 * h + unsigned(it);
return h % tableSize;
}
unsigned int hash(const string& s){
return hash(s, table_size);
}
int table_size = 103;
vector<Node> table;
typedef typename vector<Node>::iterator iter;
public:
//default constructor
hashmap(){
table = vector<Node>(table_size);
}
//copy constructor
hashmap(const hashmap& x){
table = x.table;
//for (auto it = )
}
//assignment operator //has been removed
hashmap& operator=(const hashmap& x){
this->table.erase(this->table.begin(), this->table.begin() + 103);
for ( int i = 0; i < x.table_size; i++){
this->table.push_back(x.table.at(i));
}
return *this;
}
//destructor
~hashmap(){
table.clear();
}
//index operator
T& operator[](const string x){
int h = hash(x, table.size());
if (table[h].Key == x){
return (table[h].value);
}
else {
Node* n = new Node(x);
table[h] = *n;
return (table[h].value);
}
}
//Node test
void okay(const string x,int i){
Node *temp = new Node(x, i);
cout << temp->status << endl;
/*cout << table[1].status << endl;
cout << table[2].status << endl;
table.at(0) = (*temp);
cout << table[0].Key << endl;
cout << table[0].value << endl;
cout << table[3].status << endl;*/
}
int stride(int x){
return (7-x%7);
}
//find()
iter find(const string& x){
int h = hash(x);
int s = stride(h);
int t = table_size;
int z;
//for (int i = 0; i < t; i++){
for (int i = hash(x, table_size) % t; i != t; i = (i + stride(h)) % t){
z = (h + i*s) % table_size;
if (table[z].status == open) return NULL;
if (table[z].status == deactivated) continue;
if (table[z].Key == x) return &table[h];
}
return table.end();
}
//begin()
iter begin(){
return table.begin();
}
//end()
iter end(){
return table.end();
}
};
#endif // !HASHMAP_H
Everything seems to be working fine except the find function. It's suppose to probe through the vector and return values upon conditions but the problem I'm having is I get these errors about return type conflicts.
Error2error C2664: 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap::Node>>>::_Vector_iterator(const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap::Node>>> &)' : cannot convert argument 1 from 'hashmap<int>::Node *' to 'const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>> &'
Error1error C2664: 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>>::_Vector_iterator(const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>> &)' : cannot convert argument 1 from 'int' to 'const
std::_Vector_iterator<std::_Vector_val<std::_Simple_types<hashmap<int>::Node>>> &'
How can I edit the iterator to fix this?
thank you.

boost::variant vs. polymorphism, very different performance results with clang and gcc

I'm trying to figure out how much the execution time of boost::variant differ from a polymorphism approach. In my first test I got very different results on gcc 4.9.1 and clang+llvm 3.5.
You can find the code below. Here are my results:
clang+llvm
polymorphism: 2.16401
boost::variant: 3.83487
gcc:
polymorphism: 2.46161
boost::variant: 1.33326
I compiled both with -O3.
Is someone able to explain that?
code
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <ctime>
struct value_type {
value_type() {}
virtual ~value_type() {}
virtual void inc() = 0;
};
struct int_type : value_type {
int_type() : value_type() {}
virtual ~int_type() {}
void inc() { value += 1; }
private:
int value = 0;
};
struct float_type : value_type {
float_type() : value_type() {}
virtual ~float_type() {}
void inc() { value += 1; }
private:
float value = 0;
};
void dyn_test() {
std::vector<std::unique_ptr<value_type>> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(new int_type());
else
v.emplace_back(new float_type());
}
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), [](auto &item) { item->inc(); });
}
}
struct visitor : boost::static_visitor<> {
template <typename T> void operator()(T &item) { item += 1; }
};
using mytype = boost::variant<int, float>;
void static_test() {
std::vector<mytype> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(0);
else
v.emplace_back(0.f);
}
visitor vi;
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), boost::apply_visitor(vi));
}
}
template <typename F> double measure(F f) {
clock_t start = clock();
f();
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
return seconds;
}
int main() {
std::cout << "polymorphism: " << measure([] { dyn_test(); }) << std::endl;
std::cout << "boost::variant: " << measure([] { static_test(); }) << std::endl;
return 0;
}
assembler
gcc
clang+llvm
Clang is known to miscompile some std::vector functions from various Standard libraries, due to some edge cases in their inliner. I don't know if those have been fixed by now but quite possibly not. Since unique_ptr is smaller and simpler than boost::variant it's more likely that it does not trigger these edge cases.
The code you post is practically "Why boost::variant is great". A dynamic allocation and random pointer index in addition to the regular indirections that both perform? That's a heavy hit (relatively).

Resources