2015-09-10 4 views
4

Я написал программу для преобразования отсортированного массива в BST в C++ с использованием классов. Я получаю следующие ошибки:'T' не является допустимым аргументом типа шаблона для параметра 'T'

error C2143: syntax error : missing ';' before '*' 

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 

error C2065: 'T' : undeclared identifier 

error C2923: 'Binary_Search_Tree' : 'T' is not a valid template type argument for parameter 'T' 

Следующая моя программа:

template <class T> 
class Binary_Search_Tree { 
public: 
    struct Bst_Node { 
     T value; 
     Bst_Node* left; 
     Bst_Node* right; 
    }; 

    Bst_Node* root; 

    Binary_Search_Tree(); 

    Bst_Node* sortedarraytobst(T* A, int start, int end); 
}; 

template <class T> Binary_Search_Tree<T>::Binary_Search_Tree() { 
    root = nullptr; 
    std::cout << "Constructor called" << std::endl; 
} 

template <class T> Bst_Node* Binary_Search_Tree<T>::sortedarraytobst(T* A, int start, int end) { 

    if(start > end) 
     return NULL; 

    int mid = start + (end - start)/2; 
    Bst_Node* newnode = new Bst_Node(); 
    newnode->value = A[mid]; 
    newnode->left = sortedarraytobst(A,start,mid-1); 
    newnode->right = sortedarraytobst(A,mid+1,end); 

    return newnode; 
} 

int main() 
{ 
    Binary_Search_Tree<int> tree; 
    int Array[10] = {1,2,5,6,8,9,12}; 
    int n = sizeof(Array)/sizeof(Array[0]); 
    tree.root = tree.sortedarraytobst(Array,0,n-1); 

    return 0; 
} 

Запрос помощь в этом отношении. Я считаю использование шаблонов очень запутанным.

ответ

4

В возвращаемом значении sortedarraytobst вы должны заменить Bst_Node* на typename Binary_Search_Tree<T>::Bst_Node*. Когда он вводится как возвращаемый тип, он рассматривается как «вне класса», поэтому он не может разобрать Bst_Node*.

+0

Спасибо много @ Voidstar. Это сработало. Но у меня есть некоторые вопросы: когда нам нужно использовать ключевое слово «typename»? Что вы подразумеваете под «видимым как вне класса»? Структура уже определена внутри права класса, поэтому почему она не может использоваться непосредственно в качестве возвращаемого типа? Почему это требуется только для типа возврата, а не для параметра (T * A)? – Vandana

+0

Если вы попытаетесь создать его, и получите ошибку, например, «зависимое имя не является типом» (отличается от компилятора), тогда вам нужно добавить 'typename'. После того, как вы сделаете достаточно, это как рефлекс ... просто добавьте typename, где компилятор хочет, чтобы вы :). Но почему, в основном, это необходимо, когда вы ссылаетесь на тип, который зависит от 'T' (любой аргумент шаблона), чтобы получить доступ к содержащемуся типу. Это делает его зависимым именем, требующим «typename», чтобы он знал, что это тип. См. Http://en.cppreference.com/w/cpp/language/dependent_name. Но 'T' не считается самостоятельным именем. – VoidStar

2

Как Binary_Search_Tree<T>::Bst_Node является зависимым именем, определение:

template <class T> 
Bst_Node* Binary_Search_Tree<T>::sortedarraytobst(T* A, int start, int end) 
{/**/} 

следует заменить

template <class T> 
typename Binary_Search_Tree<T>::Bst_Node* 
Binary_Search_Tree<T>::sortedarraytobst(T* A, int start, int end) 
{/**/} 

или (с C++ 11)

template <class T> 
auto Binary_Search_Tree<T>::sortedarraytobst(T* A, int start, int end) 
-> Bst_Node* 
{/**/} 
+0

C++ 14 требуется, чтобы возвращаемый тип был 'auto'. – VoidStar

+0

@VoidStar: тип возврата для трейдинга был введен в C++ 11, тип возвращаемого типа был с C++ 14. – Jarod42