An overloaded function template has never been called

I like the templates, at least if I understood them ;-). I applied an overloaded statement using templates. Now I'm trying to specialize function calls.

That's what I'm doing:

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'm 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, by executing the code, it prints the address of test3, not all the elements. I came to the conclusion that the compiler believes that

 Terminallog & operator<<(const T &v); 

is the best match. However, I do not know what to do about it. Where is the error in my code? Why

 Terminallog & operator<<(const std::vector<T> *v); 

never called?

+4
source share
2 answers

The type test3 in your code is std::vector<int> * , but there is no Terminallog::operator<< that takes an argument of this type. There is one that takes const std::vector<int> * , and it will be called if you did

 clog << const_cast<const vector<int>*>(test3); 

By the way, vector innovation is almost never a good idea.

+5
source

To match the version with a constant-pointer-vector, you need to add a constant to the type, and this is not a top-level constant (const-pointer-to-vector, i.e. std::vector<T>* const ). The selected overload does not require any type conversions and is better suited.

I would suggest completely removing pointer overloading, especially considering that it simply duplicates vector overloading. Instead, just look for the pointer.

 clog << *test3; 
+4
source

Source: https://habr.com/ru/post/1345713/


All Articles