Конструктор ограничивающего элемента шаблона C ++ - PullRequest
1 голос
/ 17 августа 2011

Это мое первое знакомство с шаблонами C ++, и я пытаюсь создать шаблон BinaryTree, чтобы помочь мне с проблемой Project Euler; однако, я, кажется, получаю ошибку, когда класс BinaryTree не распознает все конструкторы BinaryTreeNode! Вот фрагмент кода.

template <class T>
class BinaryTreeNode
{
private:
    BinaryTreeNode<T>* _left;
    BinaryTreeNode<T>* _right;
    T* _value;

public:
    BinaryTreeNode();
    explicit BinaryTreeNode(const T& value) : _value(&(T(value))) {}
    BinaryTreeNode(BinaryTreeNode<T>& left, BinaryTreeNode<T>& right, const T& value) :
        _left(&left), _right(&right), _value(&(T(value))){}
};

Класс BinaryTree

#include "BinaryTreeNode.h"
template <class T>
class BinaryTree
{
private:
    BinaryTreeNode<T>* _root;
    BinaryTreeNode<T>* _current;
    unsigned int size;

public:
    BinaryTree() : size(0), _root(0), _current(0) { }
    explicit BinaryTree(BinaryTree<T>& leftTree, BinaryTree<T>& rightTree, const T& value) : 
        size(leftTree.Size() + rightTree.Size() + 1), _root(leftTree.Root(), rightTree.Root(), value), _current(_root) {}
    explicit BinaryTree(const T& value) : size(1), _root(value) {}
    const BinaryTreeNode<T>& Root() const { return *_root;}
};

Я получаю эти ошибки.

error C2359: 'BinaryTree<T>::_root' : member of non-class type requires single initializer expression
error C2440: 'initializing' : cannot convert from 'const int' to 'BinaryTreeNode<T> *'
error C2439: 'BinaryTree<T>::_root' : member could not be initialized

Конструктор BinaryTreeNode из (BinaryTreeNode<T>&, BinaryTreeNode<T>&, const T& value) работает, когда я включаю его в основной код, но, похоже, он не работает в моем шаблоне BinaryTree. Кто-нибудь знает почему?

Ответы [ 3 ]

4 голосов
/ 17 августа 2011

В вашем выражении инициализации _root(leftTree.Root(), rightTree.Root(), value), _root является указателем .Вы можете только инициализировать его другим указателем.Возможно, вы хотите инициализировать его указателем на новый узел, построенный на этих аргументах?

Это можно сделать так: ( обновлено после вашего редактирования )

_root(new BinaryTreeNode<T>(leftTree.Root(), rightTree.Root(), value))

Однако это очень опасно (подумайте об исключении при распределении), и вам, вероятно, следует избегать использования необработанных указателей в дизайне вашего класса и вместо этого использовать интеллектуальные управляющие указатели.

Аналогично, инициализатор _root(value)делает не то, что вам нужно:

_root(new BinaryTreeNode<T>(value))

(Также обратите внимание, что вы должны инициализировать элементы в порядке их объявления.)

Обновление: я изменил первый вызов конструктора после вашего редактирования, но, как говорит @Luc, ваши конструкторы принимают неконстантные аргументы, но Root() предоставляет только константную ссылку, поэтому вам все еще нужно это исправить.

3 голосов
/ 17 августа 2011

Вы пропустили ; после обоих объявлений классов!

template <class T>
class BinaryTreeNode
{
private:
    BinaryTreeNode<T>* _left;
    BinaryTreeNode<T>* _right;
    T* _value;

public:
    BinaryTreeNode();
    explicit BinaryTreeNode(const T& value) : _value(&(T(value))) {}
    BinaryTreeNode(BinaryTreeNode<T>& left, BinaryTreeNode<T>& right, const T& value) :
        _left(&left), _right(&right), _value(&(T(value))){}
};

template <class T>
class BinaryTree
{
private:
    BinaryTreeNode<T>* _root;
    BinaryTreeNode<T>* _current;
    unsigned int size;

public:
    BinaryTree() : size(0), _root(0), _current(0) { }
    explicit BinaryTree(BinaryTree<T>& leftTree, BinaryTree<T>& rightTree, const T& value) : 
        size(leftTree.Size() + rightTree.Size() + 1), _root(leftTree.Root(), rightTree.Root(), value), _current(_root) {}
    explicit BinaryTree(const T& value) : size(1), _root(value) {}
};
0 голосов
/ 17 августа 2011

Я считаю, что вам нужен конструктор в виде BinaryTree<T>();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...