0

I have in my header a typedef which is a member of class cl1

template <size_t d>
class my_wkspc::cl1 {
  public:
    typedef std::vector<real> table_t;
    ...
    typename my_wkspc::cl2<d>& getCl2() { return _cl2; }  // <------ Not yet used
    ...
  private:
    typename my_wkspc::cl2<d>& _cl2;  // <------ Not yet used
};

and I need that typedef for a class member and functions in class cl2

namespace my_wkspc {
template <size_t d>
class cl2 {
  public:
    typename cl1<d>::table_t& getTable() const { return _table; }
    ...
  private:
    typename cl1<d>::table_t& _table;
    ...
};

Now I also need to define cl1 class members of type cl2 (not yet implemented). I think that I could forward declare cl2, and place any cl1 member function requiring knowledge of cl2 in a source file (PS: this would break my header-only classes).
But can I place cl2 class definition above cl1, with some kind of forward-declaration of typedef std::vector<real> table_t?

In Forward declare typedef within C++ class it is asked something similar (even more difficult, with reciprocal uses of typedefs), but the OP is very old, and answers (stating this is not doable) might exclude later alternatives. A late template instantiation is suggested.

Related:

  1. Forward-declare a typedef
  2. Forward declaring a typedef for a template class
  3. Forward declare a class's public typedef in c++
  4. Forward declaration of a forward-declared class member
  5. Forward declaration of a typedef in C++
  6. Forward declaring a template's member typedef
  • To forward template class, you might do: `template class cl2;`. – Jarod42 Aug 03 '21 at 09:52
  • Problem is cyclic dependency between `cl1` and `cl2`. This is very strong coupling and you have two choices: break cycle, place both class templates in single header file and fight with forward declaration. – Marek R Aug 03 '21 at 10:00
  • @Jarod42 - I know, and that is part of one option (I would call it a workaround in my case) I posted in the OP. – sancho.s ReinstateMonicaCellio Aug 03 '21 at 10:10

1 Answers1

0

Make a traits class that defines table_t and little else. Use it in both spots.

Forward declare templates.

template<std::size_t>class cl1;
template<std::size_t>class cl2;
template<std::size_t>struct table{
  using type=std::vector<real>;
};
template<std::size_t s>
using table_t=typename table<s>::type;

this assumes ttable_t actually depends on the template parameter. If not, just make it a plain typedef/using statement.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524