0

Apologies if you have seen this question before however it has yet to be answered, essentially in my code I have two structs, defined in separate headers and used globally throughout the project. I simply wish to use both structs (which again, are defined in two separate headers) in other cpp files than just the ones that the header file belongs to. Here is some sample code which I have tested:

class1.h

    #include "class2.h"
    #include <vector>
    #include <string>

    struct trans1{
        string name;
    };
    class class1 {

    private:
        vector <trans2> t2;

    public:
        class1();
    };

class2.h

    #include "class1.h"
    #include <vector>
    #include <string>        

    struct trans2{
        string type;
    };

    class class2{

    private:
        vector <trans1> t1;

    public:
        class2();
    };

errorlog:

    In file included from class1.h:3:0,
                     from class1.cpp:1:
    class2.h:21:13: error: 'trans1' was not declared in this scope
         vector <trans1> t1;
                 ^
    class2.h:21:19: error: template argument 1 is invalid
         vector <trans1> t1;
                       ^
    class2.h:21:19: error: template argument 2 is invalid

I understand that this is ridiculous code in a real world application however this is the simplest way I could demonstrate.

It is worth noting that if I simply comment out the declaration of vector t1 or t2 under 'private:' the code compiles without fail. It is just the fact I am using a second struct.

Any help anyone? Thanks.

Will
  • 79
  • 1
  • 1
  • 10
  • 1
    Can you put the "trans" structs in their own header file? – Neil Kirk Mar 22 '15 at 19:28
  • possible duplicate of [Using a struct across classes in c++](http://stackoverflow.com/questions/29195200/using-a-struct-across-classes-in-c) – erip Mar 22 '15 at 19:48

4 Answers4

1

Simply forward-declare the classes that will be used. Put all implementation code into a cpp file, not inline in the header.

Make the vector private. This way no file that includes the header can force code generation against an incomplete class.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • The vectors require a full declaration of the structs. This won't work unless the vectors are changed to store pointers. – Neil Kirk Mar 22 '15 at 19:32
  • I can confirm that this technique does actually work even though the class is not fully defined at the point of the declaration of the vector. http://goo.gl/tfpe90 – Richard Hodges Mar 25 '15 at 16:50
  • As I understand it there is (or was) some disagreement in the standards committee about whether it should be allowed. The arguing for allowing it, surprisingly, makes vector easier to implement efficiently. I think as things stand, what I have done should not work according to a strict standards interpretation, but in fact always does. The things you learn eh? :) – Richard Hodges Mar 25 '15 at 17:04
  • http://stackoverflow.com/questions/29262292/how-come-i-can-use-a-forward-declared-class-in-a-stdvector – Neil Kirk Mar 25 '15 at 17:20
0

you can try to forward declare trans1 in class2.h and trans2 in class1.h like this:

class2.h :

// includes
struct trans1;
// rest of your code

the same thing (but with trans2) in class1.h

Don't forget to add Include guards in your code!

  • edit: and yes, you need to change your vectors to store pointers, otherwise it won't link
  • I think this is worse because now you have to worry about how to allocate and delete the vector objects. – Neil Kirk Mar 22 '15 at 19:40
0

If You were to do this in single .cpp file, the solution would be trivial:

   struct trans1 { ... };
   struct trans2 { ... };
   class class1 { ... };
   class class2 { .... };

Now you just need to rearrange the code to get this result in every translation unit. (the order of classes/structs in the file is important)

tp1
  • 1,197
  • 10
  • 17
0

You need to put the "trans" structs in their own header file(s) and include them in your class header files.

You could forward declare them, but this would require changing your vector to use pointers. (In that case I would recommend std::vector<std::unique_ptr<trans>>). This could be appropriate if your structs are big and complex.

The main advantage of the forward-declaration approach is to reduce compile times. However if the structs are really so simple as in your example, I wouldn't bother with the extra overhead of using pointers here.

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91