Project

General

Profile

impossible includes with Visual Studio

Added by yvan vander sanden almost 8 years ago

Suppose you define two classes (Project and User) for a database. There is a relationship between the field "owner" and the class User. And I would like to add natural primary key to the User class.

The Project class looks like this:

class User;

class Project
{
public:
  std::string dbName; // the name of the project's database
  dbo::ptr<User> owner; // the user owning this project

  template<class Action>
  void persist(Action& a) {
    dbo::field(a, dbName, "dbName");
    dbo::belongsTo(a, owner, "owner");
  }
};

And here's the User class:

class User;
class Project;

namespace Wt {
  namespace Dbo {
    template<>
    struct dbo_traits<User> : public dbo_default_traits{
      typedef std::string IdType;

      static IdType invalidId() { return std::string(); }

      static const char * surrogateIdField() { return 0; }
    };
  }
}

typedef Wt::Auth::Dbo::AuthInfo<User> AuthInfo;

class User {
public:
  std::string ID;
  dbo::weak_ptr<AuthInfo> authInfo;
  dbo::collection<dbo::ptr<Project> > projects;

  template<class Action> void persist(Action& a) {
    dbo::id(a, ID, "ID", 20);
    dbo::hasOne(a, authInfo, "user");  
    dbo::hasMany(a, projects, dbo::ManyToOne, "owner");
  }
};

Now, with visual studio this will get error C2079: 'dummy' uses undefined class Project, from Session_impl.h. Elsewhere in this forum, this problem is acknowledged. MSVC needs the full declaration of these class. The suggested solution is to include the header files. Meaning User.h will be included in Project.h and the other way around. This works, as long as you don't try to implement a natural primary key, like done above.

Including Project.h in User.h causes the line dbo::ptr<User> owner; to be parsed before the template specialization in User.h. Which results in another error:

error C2766: explicit specialization; 'Wt::Dbo::dbo_traits<User> has already been defined.

This can be solved by not including Project.h, but then the first problem is back.

Is this a known problem? For now I'm gonna try declaring all my database classes in the same header file. I think that should work. But I'm afraid this will make my project harder to maintain when it grows.