статический член данных (указатель класса) в аргументе по умолчанию через класс c ++ - PullRequest
0 голосов
/ 16 марта 2019

мой код файла заголовка класса AvlTree выглядит следующим образом:

template <typename T>
class AvlTree
{
public:
    template <typename T1>
    friend class AvlNode;
    AvlNode<T> *root;


    AvlTree<T>(AvlNode<T> * first=NULL);
    static inline AvlNode<T>* & create();
    const static AvlNode<T>* _default;
    void free(AvlNode<T>* &first=_default){
        if (first==NULL) {delete this->root;}
        first=NULL;
    }
    void Insert(AvlNode<T> *&t, T x);
    ...
}
template <typename T>
inline AvlNode<T>* & AvlTree<T>::create(){
    static AvlNode<T>* _default;
    return _default;
}

моя основная функция

int main() {    
    using namespace std;
    AvlTree<int> tree;
    int value;
    int tmp;
    vector<int> value0{10,9,8,7,6,2,3,4,55,5,66,67};
    for (auto i = value0.begin(); i != value0.end() ; ++i) {
        tree.Insert(tree.root,*i);
    }
    tree.free();
    ...
}

Я получаю ошибки в функции-члене класса AvlTree: free ()

E:\Cprojects\C1\C3\main.cpp: In member function 'void AvlTree<T>::free(AvlNode<T>*&) [with T = int]':
E:\Cprojects\C1\C3\main.cpp:65:15: error: invalid conversion from 'const AvlNode<int>*' to 'AvlNode<int>*' [-fpermissive]
     tree.free();
               ^
E:\Cprojects\C1\C3\main.cpp:65:15: error: cannot bind rvalue '(AvlNode<int>*)AvlTree<int>::_default' to 'AvlNode<int>*&'
E:\Cprojects\C1\C3\main.cpp: In function 'int main()':
E:\Cprojects\C1\C3\main.cpp:65:15: error: invalid conversion from 'const AvlNode<int>*' to 'AvlNode<int>*' [-fpermissive]
E:\Cprojects\C1\C3\main.cpp:65:15: error: cannot bind rvalue '(AvlNode<int>*)AvlTree<int>::_default' to 'AvlNode<int>*&'
In file included from E:\Cprojects\C1\C3\main.cpp:6:
E:\Cprojects\C1\C3\AvlTree.h:143:10: note: in passing argument 1 of 'void AvlTree<T>::free(AvlNode<T>*&) [with T = int]'
     void free(AvlNode<T>* &first=_default){
          ^~~~
mingw32-make.exe[3]: *** [CMakeFiles\C3.dir\build.make:63: CMakeFiles/C3.dir/main.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:72: CMakeFiles/C3.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:84: CMakeFiles/C3.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: C3] Error 2

Если я заменю

const static AvlNode * _default;

до

статический AvlNode * _default;

Я получаю такие ошибки:

CMakeFiles\C3.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$.refptr._ZN7AvlTreeIiE8_defaultE[.refptr._ZN7AvlTreeIiE8_defaultE]+0x0): undefined reference to `AvlTree<int>::_default'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\C3.dir\build.make:180: C3.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:72: CMakeFiles/C3.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:84: CMakeFiles/C3.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: C3] Error 2

он успешно работает только при замене кода

AvlNode * & first = _default

до

AvlNode * & first = create ()

Почему? Это единственный способ успешно выполнить эту функцию-член класса с аргументом по умолчанию?

1 Ответ

0 голосов
/ 16 марта 2019
const static AvlNode<T>* _default; 
void free(AvlNode<T>* &first=_default){

Это несовместимо. Поскольку _default является указателем на const-объект, его нельзя передать функции, которая ожидает ссылку на указатель на изменяемый объект.

Вторая ошибка не связана: вы также должны определить статические переменные, а не просто объявить их:

template <typename T>
AvlNode<T>* AvlTree<T>::_default = nullptr;
...