2

错误

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>]

堆栈.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;
}

std::string想了解为什么从to发生转换std::basic_string<char>

请随时评论代码质量。

4

3 回答 3

7

实际的问题是您试图将引用传递给在参数中创建的对象,而不是存储在变量中。看到那个T&论点了Stack<T>::push吗?你不能在这里传递你的临时文件,因为它是一个非const参考。尝试如下...

Stack<T>& push(const T&);

将此签名也用于您的实现。


话虽这么说,知道那std::string只是 typedef over std::basic_string<char>。这是因为字符串的功能也可以扩展到其他字符类型—— std::wstringfor wchar_tstd::u16stringforchar16_tstd::u32stringfor char32_t。;-)

请参阅C++11 规范的§21.4 类模板basic_string[basic.string]

// basic_string typedef names
typedef basic_string<char> string;
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
typedef basic_string<wchar_t> wstring;

请注意,您不应该依赖于为您iostream包含string。您还应该包括cstring并指定memcpy调用的范围。


顺便说一句,你真的应该考虑使用Stack构造函数的初始化列表......见下文。

Stack(int length = 8) : length_(length), array_(new T[length]), last_(array_) { }

请注意,这在作为类成员声明array_之前正常运行;-)last_


...最后一点pop是不正确的,因为您将元素返回顶部。相反,请尝试以下操作...

template<typename T>
T Stack<T>::pop() {
    if (array_ != last_) {
        return *--last_;
    }
    /* other stuff here */
}

您需要在取消引用之前last_递减,因为点超过了顶部。作为旁注,您还返回了std::stringfrom的副本pop,即使您声明要避免这样做。

请注意,您不应该返回NULL,因为这不是指针类型。实际上,您将只是std::string通过构造函数创建一个带有const char *... 的构造函数,这在NULL. 见§21.4.2¶8-9...

basic_string(const charT* s, const Allocator& a = Allocator());

要求: s不得为空指针。

于 2012-09-15T03:14:06.207 回答
1

std::string是一个 typedef,因为std::basic_string<char>它没有被转换为它,它就是它。原因是可以使用相同的std::basic_string模板wchar_t来拥有 unicode 字符串。

于 2012-09-15T03:11:30.657 回答
1

因为这才是std::string真正的 - 它只是 `std::basic_string' 的别名:

typedef basic_string<char> string;

当编译器报告错误消息时,它显示的是 typedef 的真实基类型,而不是别名。

于 2012-09-15T03:14:28.370 回答