为什么我收到错误,“对类型 'std::basic_string<char>' 的非常量左值引用无法绑定到不相关类型 'const char [4]' 的值”

问题描述 投票:0回答:2

我有一个队列,最初使用字符串,现在我向其中添加了模板,这样如果我决定添加 int 双精度等,它仍然可以工作。当使用字符串添加到我的队列时,我收到一个错误,其中显示“对类型 'std::basic_string' 的非常量左值引用无法绑定到不相关类型 'const char [4]' 的值”。这是否意味着它正在将字符串类型读取为字符类型?

#include <iostream>
using namespace std;

template <class Type>
struct Node {
  Type data;
  Node<Type>* nextNode;
  Node(Type& data) : data(data), nextNode(nullptr) {}
};

template <class Type>
class Queue {
  public:
  Node<Type>* head;
  Node<Type>* tail;

  Queue() : head(nullptr), tail(nullptr) {}

  ~Queue(){
    while (!isEmpty()){
      remove();
    }
  }

  bool isEmpty() {
   return head == nullptr;
  }

  void add(Type &data){
    Node<Type>* newNode = new Node<Type>(data);
    if (isEmpty()){
      head = newNode;
      tail = newNode;
    } else {
      Node<Type>* temp = tail;
      temp->nextNode = newNode;
      tail = newNode;
    }
  }

  void remove(){
    if (isEmpty()){
      std::cout << "Not able to remove from empty queue.";
      return;
    }
    Node<Type>* temp = head;
    head = head->nextNode;
    delete temp;
  }

  Type peek(){
    if (isEmpty()){
      cout << "Queue is empty. ";
      return Type();
    }
    return head->data;
  }

};

template <class Type>
ostream &operator << (ostream &out, const Queue<Type> &s){
  Node<Type>* temp = s.head;
  while (temp != nullptr) {
    out << s.head->data << " ";
    temp = temp->nextNode;
  }
  return out;
}

void fillQueue(Queue<string> &queue) {
  queue.add("one");
  queue.add("two");
  queue.add("three");
  queue.add("four");
  cout << queue << endl;
}

void check(string name, const string shouldBe, string currentlyIs) {
  if (shouldBe == currentlyIs) {
    cout << name << ": Passed " << endl;
  } else {
    cout << name << ": Failed, value should be " << shouldBe
         << " but is returning " << currentlyIs << endl;
  }
}

void check(string name, bool shouldBe, bool currentlyIs) {
  if (shouldBe == currentlyIs) {
    cout << name << ": Passed " << endl;
  } else {
    cout << name << ": Failed, value should be " << shouldBe
         << " but is returning " << currentlyIs << endl;
  }
}

void testIsEmpty() {
  Queue<string> queue;
  check("1. Checking Empty Queue", queue.isEmpty(), true);
  queue.add("one");
  queue.remove();
  check("2. Checking Recently Empty Queue", queue.isEmpty(), true);
}

void checkQueueOrder() {
  Queue<string> queue;
  fillQueue(queue);
  string txt = "one";
  check("3. Check Front: ", queue.peek(), txt);
  queue.remove();
  txt = "two";
  check("4. Check Second: ", queue.peek(), txt);
}


int main() {
  testIsEmpty();
  checkQueueOrder();
}

这些是我收到这些错误的行:

void fillQueue(Queue<string> &queue) {
  queue.add("one");
  queue.add("two");
  queue.add("three");
  queue.add("four");
  cout << queue << endl;
}

还有这个功能

  void add(Type &data){
    Node<Type>* newNode = new Node<Type>(data);
    if (isEmpty()){
      head = newNode;
      tail = newNode;
    } else {
      Node<Type>* temp = tail;
      temp->nextNode = newNode;
      tail = newNode;
    }
  }

我收到一条注释:“注意:在此处将参数传递给参数‘data’ void add(Type &data){”

I tried using variables:
void fillQueue(Queue<string> &queue) {
string x = "one"
queue.add(x);
queue.add("two");//etc etc.
queue.add("three");
queue.add("four");
cout << queue << endl;
}   

我也尝试使用 int 类型,并弹出类似的错误。 (我更改了代码以采用整数而不是字符串)

void fillQueue(Queue<int> &queue) {
  queue.add(1);
  queue.add(2);
  queue.add(3);
  queue.add("4);
  cout << queue << endl;
}
c++ templates constants lvalue
2个回答
0
投票

const char [4]
类型来自字符串文字
"two"
——这是不可修改内存的四个字节(包括字符串的空终止符)。

这里的错误是你的成员函数

add(Type&)
正在接收一个lvalue引用,这本质上意味着一些可修改的东西(例如属于调用者的一些非常量变量)。但不允许您在运行时更改字符串文字。编译器无法将其转换为临时
std::string
,然后将 that 绑定到引用,因为语言不允许这样做。

为了轻松解决问题,您应该进行参考

const
。这将允许编译器自动将其转换为临时
std::string
并将其绑定到引用:

void add(const Type &data)
{
    // ...
}

作为一般规则,如果函数不需要修改所引用的数据,那么您应该将其设置为 const。


0
投票

问题是,当您编写queue.add("one")

时,您将字符串文字作为参数传递给
add
,但该成员函数的参数是
std::string&
类型,无法绑定到该参数。

解决方案

解决方案是在参数中添加一个

low-level const,如下所示:

//-------vvvvv---------------->added const here void add(const Type &data);
    
© www.soinside.com 2019 - 2024. All rights reserved.