0

I am trying to implement a class vec which looks like class vector everything is ok until I tried to defined an embedded class method that returns an enum hack value outside the Outer class.

Here is my interface:

#define MAX  1000

template <class T>
class vec{
    public:
        // ctors, dtor, oper. over...
        // Exeption handling
        class CExcep {
            public:
                virtual void what()const = 0;
        };

        class COutBound : public CExcep {
            public:
                enum RANGE_ERROR {
                    NEGATIVE, TOO_BIG
                };

                COutBound(const int, const RANGE_ERROR);

                const int getIndex()const;// { return index};
                const RANGE_ERROR getError()const;// { return or ; }

                virtual void what()const;
            private:
                const int index;
                const RANGE_ERROR or;
        };

    private:
        // some member data here
};

Above I embedded the CExcep base class inside my class vec and I used inheritance to use catch easily to catch exceptions through a base class reference.

  • I didn't provide implementation for the sake of brevity.

So The problem:

How can I define COutBound::getError outside class vec?

To do something like that COutBound::getIndex I managed to do that:

// ok
template<class T> 
const int vec<T>::COutBound::getIndex()const{
    return index;
}

But:

// Error here?
template<class T>
const vec<T>::COutBound::RANGE_ERROR
vec<T>::COutBound::getError()const{
    return or;
}

Simply getError returns an enum hack value of type RANGE_ERROR. If I define it inside the interface it is ok. But I want to do that outside. (separate interface from implementation).

WonFeiHong
  • 445
  • 4
  • 16
  • 1
    Do you really need to include *all* of your classes members just to ask about the nested exception classes? – StoryTeller - Unslander Monica Dec 28 '17 at 18:33
  • @StoryTeller: Should I remove them? – WonFeiHong Dec 28 '17 at 18:36
  • 1
    Your example should be a [mcve]. Make it small, and make every line of code help describe the problem, instead of being irrelevant noise. That increases the chance of people taking the time to go over it and help you. – StoryTeller - Unslander Monica Dec 28 '17 at 18:37
  • 1
    You should consider moving those nested exception classes outside, because otherwise each `vec` specialization will spawn its own exceptions incompatible with the rest. Also it would be a good idea to derive from `::std::exception` or just use appropriate standard exceptions such as `bad_alloc` `out_of_range`. – user7860670 Dec 28 '17 at 18:38
  • @VTT: Thank for the advice. In fact I'll do that next (deriving from std::exception). – WonFeiHong Dec 28 '17 at 18:43

1 Answers1

3

You need to use typename for RANGE_ERROR because it is a dependent type:

template<class T>
typename vec<T>::COutBound::RANGE_ERROR
vec<T>::COutBound::getError()const{
    return or;
}

or C++ 11 trailing return:

template<class T> auto
vec<T>::COutBound::getError()const -> RANGE_ERROR {
   return orx;
}

Also const qualifiers on simple return types are not useful and or is a reserved operator name.

user7860670
  • 35,849
  • 4
  • 58
  • 84