2014-11-27 3 views
1

Обе мои функции, Begin() и End() имеют ошибку: Member Функция не объявлена ​​в Set<T> Я также пробовал только Iterator Set<T>::begin(), у которого была такая же ошибка .. .C++ Функция члена не объявлена ​​ошибка в моем классе шаблона

#include <iostream> 
#include <vector> 

using namespace std; 

template<typename T> 
class Set 
{ 
public: 
    class Iterator; 
    void add(T v); 
    Iterator begin(); 
    Iterator end(); 

private: 
    vector<T> data; 
}; 

template<typename T> 
class Set<T>::Iterator 
{ 
public: 
    Iterator(int index, Set *s); 
    T get(); 
    void next(); 
    bool equals(Iterator s); 

private: 
    int index; 
    Set *values; 
}; 

template<typename T> 
Set<T>::Iterator::Iterator(int i, Set *s) 
{ 
    index = i; 
    values = s; 
} 

template<typename T> 
T Set<T>::Iterator::get() 
{ 
    return (*values).data[index]; 
} 

template<typename T> 
void Set<T>::Iterator::next() 
{ 
    index++; 
} 

template<typename T> 
bool Set<T>::Iterator::equals(Iterator s) 
{ 
    return (values == s.values) && (index == s.index); 
} 

template<typename T> 
Set<T>::Iterator Set<T>::begin() 
{ 
    return Iterator(0, this); 
} 

template<typename T> 
Set<T>::Iterator Set<T>::end() 
{ 
    return Iterator(data.size(), this); 
} 

template<typename T> 
void Set<T>::add(T v) 
{ 
    // 
} 

ответ

3

Короче говоря:

error: need 'typename' before 'Set<T>::Iterator' because 'Set<T>' is a dependent scope Set<T>::Iterator Set<T>::begin() ^

Как у вас есть зависимое имя, Set<T>::Iterator, вам нужно использовать typename квалифицировать, т.е. РЕПЛ ace две линии, где вы возвращаете Set<T>::Iterator в begin()/end() функции с typename Set<T>::Iterator. См

Where and why do I have to put the "template" and "typename" keywords?

для подробного объяснения. Это в основном иметь дело с декларациями формы

T::inner * x

, для которых компиляция не может надежно распознать, если вы определяете указатель на T::inner (inner определяется как внутренний class или typedef) или просто умножив T::inner (inner определяется как статический член) с x

Смотрите также

http://pages.cs.wisc.edu/~driscoll/typename.html

для конкретного примера.

PS: даже если компилятор не видит деклараций формы Type<T> * x, и в вашем случае он должен иметь возможность однозначно отклонять декларацию, она все еще «смущена» (почему? Я действительно не знаю) поэтому вам следует предшествовать любому зависимому имени типа с помощью ключевого слова typename. Цитирование: Без typename существует правило синтаксического анализа C++, в котором говорится, что квалифицированные зависимые имена должны анализироваться как не-типы, даже если это приводит к синтаксической ошибке. См

§14.6.2 [Dependent names]

из C++ 11/14 проекта https://github.com/cplusplus/draft (и, вероятно, также же разделе от стандарта, хотя я и не позволить себе купить его).

+0

Wow ... Я никогда не знал, что вам нужно было поставить typename впереди. Проводили, как час, вытягивая мои волосы. Большое спасибо –

+0

@imdumb да, это не то, чему мы учимся в старшей школе :) См. Также необходимость «шаблона», если вы все еще на этой странице. В принципе, если у вас есть 'template Foo :: memeber_function()', тогда, если вы хотите его вызвать, нужно использовать, например. 'foo.template member_function ()', поскольку в противном случае, если вы просто используете 'foo.member_function ()' компилятор считает, что первый '' 'в создании экземпляра' 'является оператором« меньше », и все ад разрывается. – vsoftco

Смежные вопросы