Error
stack.cc:53:28: error: no matching function for call to ‘Stack<std::basic_string<char> >::push(std::string)’
stack.cc:53:28: note: candidate is:
stack.cc:32:11: note: Stack<T>& Stack<T>::push(T&) [with T = std::basic_string<char>]
stack.cc
#include<iostream>
template <typename T>
class Stack {
private:
T* array_;
int length_;
T* last_;
void expandArray();
public:
Stack(int length = 8) {
array_ = new T[length];
length_ = length;
last_ = array_;
}
Stack<T>& push(T&);
T pop();
};
template<typename T>
void Stack<T>::expandArray() {
T* array_temp = new T[length_ << 1];
memcpy(array_temp, array_, length_);
std::swap(array_, array_temp);
delete[] array_temp;
length_ <<= 1;
}
template<typename T>
Stack<T>& Stack<T>::push(T& data) {
if (last_ == (array_ + length_ - 1)) {
expandArray();
}
last_[0] = data;
last_++;
return *this;
}
template<typename T>
T Stack<T>::pop() {
if(array_ != last_) {
T temp = last_[0];
last_--;
return temp;
}
return NULL;
}
int main() {
Stack<std::string> s;
s.push(std::string("a"))
.push(std::string("b"))
.push(std::string("c"))
.push(std::string("d"));
std::cout << s.pop() << std::endl;
std::cout << s.pop() << std::endl;
std::cout << s.pop() << std::endl;
std::cout << s.pop() << std::endl;
}
Wanted to understand why a conversion is happening from std::string to std::basic_string<char>?
Please feel free to comment on the code quality as well.
The actual problem is that you’re attempting to pass a reference to an object created in the argument rather than stored in a variable. See that
T&argument toStack<T>::push? You cannot pass your temporary here because it’s a non-constreference. Try as follows…Use this signature for your implementation, too.
That being said, know that
std::stringis a mere typedef overstd::basic_string<char>. This is because the functionality for strings can be extended to the other character types, too —std::wstringforwchar_t,std::u16stringforchar16_t, andstd::u32stringforchar32_t. 😉See §21.4 Class template
basic_string[basic.string] of the C++11 specification.Note that you shouldn’t rely on
iostreamto includestringfor you. You should also includecstringand specify the scope for yourmemcpycall.By the way, you should really look into using an initializer list for
Stack‘s constructor… see as follows.Note that this functioning properly on
array_precedinglast_as a class member declaration 😉… AND a final note. Your
popis incorrect, since you’re returning the element past the top. Instead, try something as follows…You need to decrement prior to dereferencing, since
last_points past the top. As a side note, you’re also returning a copy of thestd::stringfrompop, even though you stated you wanted to avoid as such.Note you shouldn’t be returning
NULLsince this isn’t a pointer type. In fact, you’ll just be creating anstd::stringvia the constructor that takes aconst char *… which is explicitly prohibited in the case ofNULL. See §21.4.2¶8-9…