C++ Class and Function Template declarations? - c++

Right now I am trying to make my template class and functions run but I am not sure how to define a template void function. Here's a small part of my code attached below. The code doesn't run and for anytime in the class arrayList is used it says argument list for arrayList is missing.
#include <iostream>
using namespace std;
template<typename Type> //Template class declaration
class arrayList
{
public:
void print() const;
protected:
int *list; //array to hold the list elements
int length; //to store the length of the list
int maxSize; //to store the maximum size of the list
};
template<typename Type>
void arrayList::print() const
{
int i;
for(i = 0; i < length; i++)
cout<<list[i]<<" ";
cout<<endl;
}

Try
template<typename Type>
void arrayList<Type>::print() const ...

Related

Class template for 2 dimension array that might be used with sever data types in main()

I have to create a class template for 2 dimension array; every variable in the array would get a random value [65;90], I need to find the MAX value in the array. But in class template data type should be unspecified, so later I could use it with any - int/char etc in main().
I have tried several ways to initialize the array, however it still doesnt work. Now here is one part to put the values in the array and 2nd to print().
#include <iostream>
#include <cstdlib>
using namespace std;
template <typename T>
class Array {
private:
T **ptr;
public:
Array(T arr[7][12]);
void print();
};
template <typename T>
Array<T>::Array(T arr[7][12]) {
ptr = new T[7][12];
for(int i = 0; i < 7; i++) {
for (int j=0;j<12;j++) {
arr[i][j]=rand()%26+65;
ptr[i][j]=arr[i][j];
}
}
}
template <typename T>
void Array<T>::print() {
for(int i = 0; i < 7; i++) {
for (int j=0; j<12; j++) {
cout<<*(ptr+j)<<" ";
}
cout<<"\n";
}
cout<<endl;
}
int main() {
int arr[7][12];
Array<int> a(arr[7][12]);
a.print();
return 0;
}
If the dimensions are known at compile time and you can use std::array then you don't need to dynamically allocate the array:
#include <array>
template <typename T,unsigned M,unsigned N>
struct my_2d_array {
using row_type = std::array<T,N>;
std::array< row_type, M> data;
};
If you cannot use std::array for some reasons:
template <typename T,unsigned M,unsigned N>
struct my_2d_array {
T data[M][N];
};
Here
int arr[7][12];
Array<int> a(arr[7][12]);
you declare arr to be of size 7x12 and then access it of of bounds. The last valid element is arr[6][11] and arr[i][j] is a single element (an int) from the array.
I think that this is what you want
#include <iostream>
#include <cstdlib>
using namespace std;
template <typename T>
class Array {
private:
T **ptr;
public:
Array(T arr[][12]);
void print();
};
template <typename T>
Array<T>::Array(T arr[][12]) {
ptr = new T *[7];
for(int i = 0; i < 7; i++) {
ptr[i] = new T[12];
for (int j=0;j<12;j++) {
arr[i][j]=rand()%26+65;
ptr[i][j]=arr[i][j];
}
}
}
template <typename T>
void Array<T>::print() {
for(int i = 0; i < 7; i++) {
for (int j=0; j<12; j++) {
cout<<ptr[i][j]<<" ";
}
cout<<"\n";
}
cout<<endl;
}
int main() {
int arr[7][12];
Array<int> a(arr);
a.print();
return 0;
}
Here is ways that you can pass 2D array
Passing a 2D array to a C++ function

initialize a member of some class in initialization list if the member is a template class

[Solved]: The problem was not in template class initialization, but with code-specific issue of using undefined macro inside a template class constructor. The compiler error did not complain about undefined symbol, but was (wrongfully) related to lambdas.
I've searched for an answer but couldn't find an exact one. The closest answer is here: C++ invoke explicit template constructor but I'm not sure if that is entirely related to my question.
And my question is, how can I initialize a member of structure B in initialization list if the member is a template class?
Header ClassA.h:
#ifndef _A_
#define _A_
#include <typeinfo>
#include <windows.h>
template<class Type> class A{
int u,v;
Type** pointer;
public:
A();
A(int number);
~A();
Type& operator[] (int i){
typeid(Type);
return *pointer[i];
}
Type& Get(int i)
{
typeid(Type);
return *pointer[i];
}
Type *GetPointer(int i)
{
typeid(Type);
return pointer[i];
}
Type* add ();
Type& add(Type *element);
Type& add(Type *element, int place);
void expand(int NewLength);
void swap(Type *element, int place);
void remove(int number);
void remove(Type *element);
void removePointer(int number);
void removePointer(Type *element);
};
template<class Type>A<Type>::A(){
u = 128;
v = 10;
}
template<class Type>A<Type>::A(int number){
//some thing to do with number;
u = number;
v = 10;
New( pointer, Type *[u] );
}
template <class Type> A<Type>::~A()
{
}
template <class Type> void A<Type>::expand(int NewLength)
{
Type **NewList = NULL;
NewList = new Type*[NewLength];
}
template <class Type> Type* A<Type>::add ()
{
pointer[u] = new Type;
}
template <class Type> Type& A<Type>::add(Type *element)
{
}
template <class Type> Type& A<Type>::add(Type *element, int place)
{
}
template <class Type> void A<Type>::swap(Type *element, int place)
{
}
template <class Type> void A<Type>::remove(Type *element)
{
}
template <class Type> void A<Type>::removePointer(int nume)
{
}
template <class Type> void A<Type>::removePointer(Type *element)
{
}
#endif
Header StructB.h:
#pragma once
#ifndef _B_
#define _B_
#include "ClassA.h"
struct C{
float x,y,z;
};
struct B{
private:
B(){
}
public:
int x,y;
A<B*> member1;
A<C> member2;
B(int X,int Y) : member1(5),member2(5) {
//initialize x,y
}
void Add(B* otherB){
B** _pOtherB = new B*; (*_pOtherB) = otherB;
member1.add(_pOtherB);
}
};
#endif
The compiler complains with this error (and some other errors, I can post them if nedded):
error C3493: 'number' cannot be implicitly captured because no default capture mode has been specified
Is there any way to do this, or some workaround perhaps?
Thanks in advance :D
Either the code you've given us isn't complete, or it is broken. This line:
New(pointer, Type *[u]);
seems to be referencing either some missing member method or global function, or it is simply invalid. The error message is kinda cryptic, but that's C++ for you.
I'm going to assume that New is some kind of macro, because no normal function (even a templated one) can take this sort of type definition as a parameter. You've not given us the definition of New, so there's no way we can tell. It is probably the absense of this macro (maybe a wrapper for some sort of memory debugging system?) that is causing the crazy error.
If I replace the New line with this:
pointer = new Type*[u];
the code compiles fine.

Typedef Student is not working

I am testing an array template. It works fine for string type and int, but not for a typedef Student. I tried to figure out, but I can't find the problem. I did not use a separate compilation as it is just a test. I am using Dev-C++. Your help will be very appreciated. The code is below:
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class Array
{
public:
Array(int initialSize);
~Array();
T & operator[](int i);
private:
T * m_pData;
int m_nSize;
};
//Implementing member functions in the Array template
template <typename T>
Array <T>::Array(int initialSize)
{
m_nSize = initialSize;
m_pData = new T [m_nSize];
};
template <typename T>
T & Array <T>::operator[](int i)
{
return m_pData[i];
};
template <typename T>
Array <T>::~Array()
{
delete[] m_pData;
};
typedef struct Student{}students[0];
//test array class implementatition
int main()
{
//creating an array of 20 integers, then assigning the value 50 at index 2
Array <int> myArray (20);
myArray[2] = 50;
cout << myArray[2] <<endl;
//creating an array of string of size 10, then assigning the string "Fred" at index 5
//then display the string
Array <string> nameArray (10);
nameArray[5] = string("Fred");
cout << nameArray[5] <<endl;
//creating an array of Student of size 100, then assigning the value "123456789" at index 4
//then display the value at that index
Array <Student> students (100);
students[4] = Student("123456789"); //here is the problem!!!
///cout << students[4] <<endl;
system ("pause");
return 0;
}
Student doesn't have a constructor,you can't call Student("123456789"); Try to define a constructor for Student:
struct Student
{
Student(): age_(0), name_("") {}
Student(int age): age_(age), name_("") {}
Student(const std::string& name): name_(name){
}
int age_;
std::string name_;
};

What does "missing template argument" mean?

I'm pretty new to C++ and this site so there are bound to be errors. When I try to compile my code I get errors like error: missing template argument before 'b'. I've been searching the world for answers for hours and it has led me here.
My assignment is to implement a templated class Collection that stores a collection of
Objects using an array, along
with the current size of the collection.
#include <iostream>
#include "collection.h"
using namespace std; v
int main(int argc, char* argv[])
{
collection b; //<----error missing template argument before 'b'
return 0;
}
#ifndef COLLECTION_H
#define COLLECTION_H
#include <iostream>
template <typename obj>
class collection
{
public:
collection();
bool isEmpty() const;
void makeEmpty();
void insert(obj val);
void remove(obj val);
bool contains(obj val) const;
private:
size_t size;
obj* col[];
};
#endif
#include "collection.h"
template <typename obj>
collection<obj>::collection() :size(10)
{
col = new obj*[size];
}
template <typename obj>
bool collection<obj>::isEmpty() const
{
for(size_t k = 0; k < size; k++)
{
if(col[k] != NULL)
return false;
}
return true;
}
template <typename obj>
void collection<obj>::makeEmpty()
{
for(size_t k = 0; k < size; k++)
{
col[k] = NULL;
}
}
template <typename obj>
void collection<obj>::insert(obj val)
{
int temp = 0;
for(size_t s = 0; s < size; s++)
{
if(col[s] != NULL)
temp++;
}
if(temp >= size)
{
obj* temp = new obj*[size*2];
for(size_t c = 0; c < size; c++)
temp[c] = col[c];
delete col;
col = temp;
}
else
col[temp] = val;
}
template <typename obj>
void collection<obj>::remove(obj val)
{
for(size_t x = 0; x < size; x++)
{
if (col[x] == val)
{
for(size_t y = x; y < size-1; y++)
{
col[y] = col[y+1];
}
col[size-1] = NULL;
return;
}
}
}
template <typename obj>
bool collection<obj>::contains(obj val) const
{
for(size_t z = 0; z < size; z++)
{
if(col[z] == val)
return true;
}
return false;
}
You have to say what it's a collection of.
template <class A> class collection {}
requires that you use it as
collection<int> b;
or some appropriate type. That then makes a collection of ints. You haven't told it what you want a collection of.
First : Instantiate template by type. So if you have template <typename obj> class T {...}; you should use it like
void main {
T<int> t;
T<bool> t1; // .. etc
}
You can use a template with default value for the typename parameter defined in the class template declaration
template <typename obj = int> class T {/*...*/};
void main {
T<> t;
}
but anyway you should put empty angle brackets when use it without parameter.
Second: While declaring template, place it whole in the header file. Each definition of his methods should be in the file "*.h", don't ask me why, just don't split it to the header and "cpp" file.
Hope it helps.
Well, you're missing a template argument. You can't create a collection object, that's just a template.
You can only create e.g. a collection<int> or collection<std::string>.
You need to specify the type for template, like int or some other type:
collection<int> b;
There are a large number of errors in your code. First define your template in a header file:
In collection.h put the following:
#ifndef COLLECTION_H
#define COLLECTION_H
template <typename obj>
class collection
{
public:
collection() {}
bool isEmpty() const;
void makeEmpty();
void insert(obj val);
void remove(obj val);
bool contains(obj val) const;
private:
size_t size;
obj* col[];
};
#endif
Then in a .cpp file inside a main function do the following:
collection<int> b;
Instead of int you can use a different type but the main point is that YOU NEED A TYPE to instantiate a template.

Class member calls function template with callback function

I'm having trouble passing a callback function from within a class, when calling a template function. Here's a sample code:
sortedlist.h
#ifndef _sortedlist_h
#define _sortedlist_h
#include <vector>
template <typename ElemType>
class SortedList {
public:
SortedList(int (*compare)(ElemType a, ElemType b));
~SortedList();
void push(ElemType newElem);
ElemType pop();
private:
std::vector<ElemType> v;
int (*cmp) (ElemType first, ElemType second);
void Sort();
};
template <typename ElemType>
SortedList<ElemType>::SortedList(int (*compare)(ElemType a, ElemType b)) {
cmp = compare;
}
template <typename ElemType>
SortedList<ElemType>::~SortedList() {
}
template <typename ElemType>
void SortedList<ElemType>::push(ElemType newElem) {
v.push_back(newElem);
Sort();
}
template <typename ElemType>
ElemType SortedList<ElemType>::pop() {
ElemType next = v.back();
v.pop_back();
return next;
}
template <typename ElemType>
void SortedList<ElemType>::Sort() {
for (int i=v.size()-1; i>0; i--) {
if(cmp(v[i], v[i-1]) < 0) { //compare function
ElemType temp = v[i];
v[i] = v[i-1];
v[i-1] = temp;
}
else return;
}
}
#endif
game.h
#ifndef _game_h
#define _game_h
#include <string>
#include "sortedlist.h"
class Game {
public:
Game() {};
~Game() {};
void addPlayer(std::string name, int score);
std::string getWinner();
struct Player {
std::string name;
int score;
};
//compare function
int highScore(Player one, Player two);
private:
SortedList<Player> list(highScore);
};
#endif
game.cpp
#include "game.h"
void Game::addPlayer(std::string name, int score) {
Player newEntry;
newEntry.name = name;
newEntry.score = score;
list.push(newEntry);
}
std::string Game::getWinner() {
return list.pop().name;
}
//compare function
int Game::highScore(Player one, Player two) {
if (one.score == two.score) return 0;
if (one.score > two.score) return 1;
return -1;
}
sample main:
#include <iostream>
#include "game.h"
using namespace std;
int main () {
Game pacman;
pacman.addPlayer("Beavis", 100);
pacman.addPlayer("Butthead", 200);
cout << pacman.getWinner() << endl;
}
When I compile it on XCode, I get "'highscore' is not a type" error. I also tried moving Player and highScore outside of the class with similar results. What should I do instead?
In C++ you cannot initialize class-members in-place. You need to do that in the constructor initializer list
class Game {
public:
Game():list(highScore) {};
~Game() {};
//compare function
static int highScore(Player one, Player two);
private:
SortedList<Player> list;
};
The function needs to be declared as static in the class definition as SortedList calls it without a *this pointer, like an ordinary function.
Performance is really unnecessary bad of the comparison function because you always copy the two items to be compared when passing them as arguments. Better make the comparison function's type to receive const-references and change highScore's signature appropriately
int (*compare)(ElemType const& a, ElemType const& b);