Z
ZikO
Hi
I have just type some codes from the book to understand templates. The
code below simply put another method to vector<T> which is sort();
When learning templates in C++, I found something I don't understand.
Please, find below three codes: Sortable.h, Urand.h and main.cpp which
uses those 2 headers.
In part and full template specialization, I don't understand that at
partial specialization (when type is a pointer) I used the syntax
template<class T> class ... {}; etc.
However, at the full specialization this does not work. I had to comment
this part in Sortable.h (it can be seen right before full specialization
of the member function sort()).
If I uncomment this, compiler says:
"main.cpp:59: error: aggregate 'Sortable<char*> scp' has incomplete type
and cannot be defined"
and in the Sortable.h it says:
"..\/Sortable.h:53: error: expected template-name before '<' token
...\/Sortable.h:53: error: expected '{' before '<' token
...\/Sortable.h:53: error: expected unqualified-id before '<' token
...\/Sortable.h:63: error: invalid use of incomplete type 'class
Sortable<char*>'
...\/Sortable.h:17: error: declaration of 'class Sortable<char*>'"
Why I am not to use the same pattern as before, with template<> class
Sortable<char*> : public vector<char*> { // ... }; ?
Does it mean when I have general template and I want to put full
specialization of some methods, I can just specialize just those methods
without template<> class etc.? I am confused here :/
Below, there are 3 codes: Urand.h, Sortable.h and main.cpp
I have just type some codes from the book to understand templates. The
code below simply put another method to vector<T> which is sort();
When learning templates in C++, I found something I don't understand.
Please, find below three codes: Sortable.h, Urand.h and main.cpp which
uses those 2 headers.
In part and full template specialization, I don't understand that at
partial specialization (when type is a pointer) I used the syntax
template<class T> class ... {}; etc.
However, at the full specialization this does not work. I had to comment
this part in Sortable.h (it can be seen right before full specialization
of the member function sort()).
If I uncomment this, compiler says:
"main.cpp:59: error: aggregate 'Sortable<char*> scp' has incomplete type
and cannot be defined"
and in the Sortable.h it says:
"..\/Sortable.h:53: error: expected template-name before '<' token
...\/Sortable.h:53: error: expected '{' before '<' token
...\/Sortable.h:53: error: expected unqualified-id before '<' token
...\/Sortable.h:63: error: invalid use of incomplete type 'class
Sortable<char*>'
...\/Sortable.h:17: error: declaration of 'class Sortable<char*>'"
Why I am not to use the same pattern as before, with template<> class
Sortable<char*> : public vector<char*> { // ... }; ?
Does it mean when I have general template and I want to put full
specialization of some methods, I can just specialize just those methods
without template<> class etc.? I am confused here :/
Below, there are 3 codes: Urand.h, Sortable.h and main.cpp
Code:
/*
* Urand.h
*
* Created on: 2 Sep 2009
* Author: User
*/
#ifndef URAND_H_
#define URAND_H_
#include <bitset>
#include <cstddef>
#include <cstdlib>
#include <ctime>
using std::size_t;
using std::bitset;
template<size_t UpperBound>
class Urand {
bitset<UpperBound> used;
public:
Urand() {
srand(time(0)); // losowo
}
size_t operator()(); // funkcja generator
};
template<size_t UpperBound>
inline size_t Urand<UpperBound>::operator()() {
if(used.count() == UpperBound)
used.reset(); // i od nowa (wyczysc bitset)
size_t newval;
while(used[newval = rand() % UpperBound]);
used[newval] = true;
return newval;
}
#endif /* URAND_H_ */
Code:
/*
* Sortable.h
*
* Created on: 2 Sep 2009
* Author: User
*/
#ifndef SORTABLE_H_
#define SORTABLE_H_
#include <string>
#include <vector>
#include <cstring>
using std::size_t;
template<class T>
class Sortable : public std::vector<T> {
public:
void sort();
};
template<class T>
void Sortable<T>::sort() {
for(size_t i = this->size(); i > 0; --i)
for(size_t j = 1; j < i; ++j)
if(this->at(j-1) > this->at(j)) {
T t = this->at(j-1);
this->at(j-1) = this->at(j);
this->at(j) = t;
}
}
// Specjalizacja czesciowa dla wskaznikow
template<class T>
class Sortable<T*> : public std::vector<T*> {
public:
void sort();
};
template<class T>
void Sortable<T*>::sort() {
for(size_t i = this->size(); i > 0; --i)
for(size_t j = 1; j < i; ++j)
if(*this->at(j-1) > *this->at(j)) {
T* t = this->at(j-1);
this->at(j-1) = this->at(j);
this->at(j) = t;
}
}
// Pelna specjalizacja dla char* jako funkcja inline
//template<>
//class Sortable<char*> : public vector<char*> {
//public:
// void sort();
//};
template<>
void Sortable<char*>::sort() {
for(size_t i = this->size(); i > 0; --i)
for(size_t j = 1; j < i; ++j)
if(std::strcmp(this->at(j-1), this->at(j)) > 0) {
char* t = this->at(j-1);
this->at(j-1) = this->at(j);
this->at(j) = t;
}
}
#endif /* SORTABLE_H_ */
Code:
/*
* main.cpp
*
* Created on: 2 Sep 2009
* Author: User
*/
#include <cstddef>
#include <iostream>
#include "Sortable.h"
#include "Urand.h"
using namespace std;
#define asz(a) (sizeof a / sizeof a[0])
char* words[] = {
"is",
"running",
"big",
"dog",
"a"
};
char* words2[] = {
"this",
"that",
"theother"
};
int main() {
Sortable<int> is;
Urand<47> rnd;
for(size_t i = 0; i < 15; ++i)
is.push_back(rnd());
for(size_t i = 0; i < is.size(); ++i)
cout << is[i] << " ";
cout << endl;
is.sort();
for(size_t i = 0; i < is.size(); ++i)
cout << is[i] << " ";
cout << endl;
// wykorzystywana czesciowa specjalizacja
Sortable<string*> ss;
for(size_t i = 0; i < asz(words); ++i)
ss.push_back(new string(words[i]));
for(size_t i = 0; i < ss.size(); ++i)
cout << *ss[i] << " ";
cout << endl;
ss.sort();
for(size_t i = 0; i < ss.size(); ++i) {
cout << *ss[i] << " ";
delete ss[i];
}
cout << endl;
// Wykorzystywana calkowita specjalizacja
Sortable<char*> scp;
for(size_t i = 0; i < asz(words2); ++i)
scp.push_back(words2[i]);
for(size_t i = 0; i < scp.size(); ++i)
cout << scp[i] << " ";
cout << endl;
scp.sort();
for(size_t i = 0; i < scp.size(); ++i) {
cout << scp[i] << " ";
}
}