1

The following code results in the compiler error 'Exception' does not refer to a value

    template <typename T>
    class A {
    public:
        virtual ~A() = 0;
        class Exception {
        };
    };

    template<typename T>
    inline A<T>::~A() {}

    template <typename T>
    class B : public A<T> {
    public:
        B() {}

        ~B() {}

        void foo() {
            throw B<T>::Exception();
        }
    };
    int main()
    {
        try {
            B<int> instB = B<int>();
            instB.foo();
        }
        catch(B<int>::Exception &e) {
            std::cout << "uh oh" << std::endl;
        }
    }

but, if the type is explicitly specified into the throw, it works. It seems there is an issue in specifying the template type.

throw B<int>::Exception   // this works

From Template compilation error: 'X' does not refer to a value this is an indicate that clang is expecting 'Exception' to be a value, not a type.

What is the proper way to thrown the template class Exception?

prh
  • 105
  • 1
  • 5
  • 1
    `throw typename B::Exception();` See also: https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords – Igor Tandetnik Oct 29 '17 at 18:50
  • on gcc the compiler could fix the code itself :-): It throws the error message "note: say 'typename B::Exception' if a type is meant". BTW: For clarity you should write A because it is defined there... quite clear that B derives from A but it looks a bit strange... – Klaus Oct 29 '17 at 18:53

1 Answers1

1

As indicated by @Igor Tandetnik and @Klaus, the compiler needs to be told it's a type to disambiguate it.

void foo() { throw typename B<T>::Exception() }

or better

void foo() { throw typename A<T>::Exception() }
prh
  • 105
  • 1
  • 5