Передача указателя ссылки const не соответствует сигнатуре метода - PullRequest
0 голосов
/ 06 мая 2019

Следующий код передает ссылку на указатель const вспомогательной функции size().Это работает, только если я удаляю оператор ссылки const или & из вспомогательной функции.

#include <iostream>

using namespace std;                                                                   

template <typename T>
class Test {
   public:
      Test();
      int size();
      void insert(T);
   private:
      struct Node {
         T value;
         Node* left;
         Node* right;                                                              
      };
      Node* root;
      int size(const Node*& node);
};

template <typename T>
Test<T>::Test() { root = nullptr;}                                                                                  

template <typename T>
int Test<T>::size() {return size(root);}                                                                                  

template <typename T>
int Test<T>::size(const Node*& node) {
   if (node != nullptr)
      return 1 + size(node->left) + size(node->right);                             
   return 0;
}

int main() {
   Test<int> t;
   cout << "Size: " << t.size() << endl;
}

При компиляции этого кода в виде C ++ 11 я получаю следующие ошибки компилятора:

main.cpp:31:11: error: no matching member function for call to 'size'
   return size(root);
          ^~~~
main.cpp:43:26: note: in instantiation of member function 'Test<int>::size' requested here
   cout << "Size: " << t.size() << endl;
                         ^
main.cpp:21:11: note: candidate function not viable: no known conversion from 'Test<int>::Node *' to 'const Test<int>::Node *&' for 1st argument
      int size(const Node*& node);
          ^
main.cpp:10:11: note: candidate function not viable: requires 0 arguments, but 1 was provided
      int size();
          ^
1 error generated.

Однако, если я просто удаляю const или оператор ссылки (&) из вспомогательной функции, которую вызывает size(), он компилируется и выполняется точно так, как ожидается.

Другими словами, любой из следующих работ:

int size(Node*& node);
template <typename T> int Test<T>::size(Node*& node)
int size(const Node* node);
template <typename T> int Test<T>::size(const Node* node)

Но это не так:

int size(const Node*& node);
template <typename T> int Test<T>::size(const Node*& node)

Объявление и реализация кажутся идентичными во всех трех случаях, поэтому яс трудом выясняет, почему дело со ссылкой const не удается.

1 Ответ

1 голос
/ 06 мая 2019

Если бы было допустимо передать указатель на неконстантный объект, где ожидается ссылка на указатель на константный объект, то можно было бы нарушить правильность констант. Рассмотрим:

const int c = 42;

void f(const int*& p) {
  // Make p point to c
  p = &c;
}

int* q;
f(q);  // hypothetical, doesn't compile
// Now q points to c
*q = 84;  // oops, modifying a const object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...