1

Both my functions, Begin() and End() are having an error: Member Function not declared in Set<T> I've also tried just Iterator Set<T>::begin() which had the same error...

#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)
{
    //
}
im dumb
  • 151
  • 1
  • 4
  • 9

1 Answers1

3

Long story short:

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

As you have a dependent name, Set<T>::Iterator, you need to use typename to qualify it, i.e. replace the two lines where you return Set<T>::Iterator in begin()/end() functions with typename Set<T>::Iterator. See

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

for a detailed explanation. It basically have to do with declarations of the form

T::inner * x

for which the compile cannot reliably recognize if you are defining a pointer to T::inner (inner being defined as an inner class or typedef) or simply multiplying T::inner (inner being defined as a static member) with x

See also

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

for a specific example.

PS: even if the compiler doesn't see declarations of the form Type<T> * x, and in your case it should be able to disambiguate the declaration, it is still "confused" (why? I don't really know), so you should precede any dependent typename by the typename keyword. Citing: Without typename, there is a C++ parsing rule that says that qualified dependent names should be parsed as non-types even if it leads to a syntax error. See

§14.6.2 [Dependent names]

from the C++11/14 draft https://github.com/cplusplus/draft (and probably also the same section from the standard, although I didn't afford to buy it).

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Wow...I never knew that you had to put typename in front. Spent like an hour pulling my hair out. Thanks a lot – im dumb Nov 27 '14 at 00:44
  • @imdumb yeah, it is not something we learn in high school :) See also the need for `template` if you are still on this page. Basically, if you have a `template Foo::memeber_function()`, then if you want to call it, have to use e.g. `foo.template member_function()`, as otherwise if you just use `foo.member_function()` the compiler believes that the first `<` in the template instantiation `` is the "smaller than" operator, and all hell breaks loose. – vsoftco Nov 27 '14 at 00:47