C++ Forward declare using directive

You can't declare a using alias without defining it. You can declare your class template without defining it, however, and use a duplicate using alias:

namespace fancy {
    template <typename> class Foo;
    class Bar;
    using FooBar = Foo<Bar>;
}

Another way to use forward declare is to replace using with the class inheritance:

// using FooBar = Foo<Bar>;
class FooBar : public Foo<Bar> {};

Of course, now FooBar is not the same thing as Foo<Bar>. For instance, you need to inherit possibly existente constructors via using Foo<Bar>::Foo, but as a profit you can use easy forward declare as usual. Just:

namespace fancy {
    class FooBar;
}

If your using declaration is too large (a lot of template parameters, which on their turn are also defined by a using statement), you could also add a dummy forward struct that has the using type as a dependent type:

    namespace fancy {

        struct Bar {
            ...
        }

        template<typename T>
        class Foo {
            ...
        }

        using FooBar = Foo<Bar>;

        // Forward struct
        struct FooBarFwd {
            using type = FooBar;
        }
    }

Then in your place where you want to forward declare:

    namespace fancy {
        class FooBarFwd;
    }
    // use your type as
    typename FooBarFwd::type baz(const typename FooBarFwd::type & myFooBar);
    // instead of
    // FooBar baz(const FooBar & myFooBar);

Some disadvantages of this approach are

  • Using typename to disambiguate the dependent type.
  • Extra indirection for your type, some compilers could have problems when reporting errors.
  • Changing to this approach might need quite a lot of changes to your code (changing every occurence of FooBar with typename FooBarFw::type)

Therefore, I advise to apply this technique only when you are certain what you are doing.

Tags:

C++

C++11