I love templates, at least I would if I would understand them ;-). I implemented an overloaded operator using templates. I am now trying to specialise the function calls.
Here is what I do:
class Terminallog {
public:
Terminallog();
Terminallog(int);
virtual ~Terminallog();
template <class T>
Terminallog & operator<<(const T &v);
template <class T>
Terminallog & operator<<(const std::vector<T> &v);
template <class T>
Terminallog & operator<<(const std::vector<T> *v);
template <class T, size_t n>
Terminallog & operator<<(const T(&v)[n]);
Terminallog & operator<<(std::ostream&(*f)(std::ostream&));
Terminallog & operator<<(const char v[]);
//stripped code
};
//stripped code
template <class T>
Terminallog &Terminallog::operator<<(const T &v) {
if (this->lineendet == true) {
this->indent();
}
this->lineendet = false;
std::cout << v;
return *this;
}
template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> &v) {
for (unsigned int i = 0; i < v.size(); i++) {
std::cout << std::endl;
this->indent();
std::cout << i << ": " << v.at(i);
}
std::cout << std::flush;
return *this;
}
template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> *v) {
for (unsigned int i = 0; i < v->size(); i++) {
std::cout << std::endl;
this->indent();
std::cout << i << ": " << v->at(i);
}
std::cout << std::flush;
return *this;
}
template <class T, size_t n>
Terminallog &Terminallog::operator<<(const T(&v)[n]) {
unsigned int elements = sizeof (v) / sizeof (v[0]);
for (unsigned int i = 0; i < elements; i++) {
std::cout << std::endl;
this->indent();
std::cout << i << ": " << v[i];
}
std::cout << std::flush;
return *this;
}
inline
Terminallog &Terminallog::operator<<(std::ostream&(*f)(std::ostream&)) {
if (f == static_cast<std::ostream & (*)(std::ostream&)> (std::endl)) {
this->lineendet = true;
}
std::cout << f;
return *this;
}
inline
Terminallog &Terminallog::operator<<(const char v[]) {
if (this->lineendet == true) {
std::cout << std::endl;
this->indent();
std::cout << v;
}
this->lineendet = false;
std::cout << v;
return *this;
}
//sripped code
Now I am trying something like
vector<int> *test3 = new vector<int>;
test3->push_back(1);
test3->push_back(2);
test3->push_back(3);
test3->push_back(4);
Terminallog clog(3);
clog << test3;
which compiles just fine. However executing the code, it prints the address of test3, instead all the elements. I conclude that the compiler thinks, that
Terminallog & operator<<(const T &v);
is a better match. However I don’t know what to do about it. Where is the mistake in my code? Why is
Terminallog & operator<<(const std::vector<T> *v);
never called?
The type of
test3in your code isstd::vector<int> *, but there is noTerminallog::operator<<that takes an argument of that type. There is one that takesconst std::vector<int> *and it would be called if you didIncidentally, new’ing a vector is almost never a good idea.