0

I am using an external library named custom (not the actual name) which defines many of its data types in its own namespace. Let's assume that the namespace is named as custom as well.

I am trying to make use of a datatype named DataType. DataType is a custom type defined using a typedef, and let's assume that it can be used in a .cpp file by including "custom/datatype.h"

My code has the following setting.

action.h:

class Action
{
    Action() {}
    virtual ~Action() {}

    virtual void foo(custom::DataType*) const = 0;
    ...
}

some_action.h:

#include "action.h"

class SomeAction : public Action
{
    SomeAction() {}

    virtual void foo(custom::DataType*) const override;
    ...
}

some_action.cpp:

#include "some_action.h"
#include "custom/datatype.h"
...
void SomeAction::foo(custom::DataType*) const
{
    ...
}

Is there any proper way to forward-declare DataType in action.h and some_action.h other than including "custom/datatype.h" in action.h?

ilim
  • 4,477
  • 7
  • 27
  • 46
  • http://stackoverflow.com/questions/2059665/why-cant-i-forward-declare-a-class-in-a-namespace-like-this – Alex Apr 27 '17 at 09:24
  • does your code compile? In action.h you need at least a forward declaration of `DataType` – 463035818_is_not_an_ai Apr 27 '17 at 09:37
  • @tobi303 My code does not compile, indeed. That's why I was asking how to proceed with this issue. If I compile the code as it currently is, the compiler considers the `custom` and `DataType` in header files to be undefined. If I forward-declare as suggested in the response by Vittorio Romeo, I get another error. (see my comment to his response for the actual error) – ilim Apr 27 '17 at 09:41
  • in such a case you should include the error message in the question – 463035818_is_not_an_ai Apr 27 '17 at 09:49

2 Answers2

2

Is there any proper way to define DataType in action.h and some_action.h other than including "custom/datatype.h" in action.h?

You probably don't want to "define" DataType, but to "forward declare" it instead. This allows you to make the compiler aware of a custom::DataType which will be defined later.

You can achieve this as follows. In action.h and some_action.h add the following forward declaration:

namespace custom { class DataType; }

In the .cpp files where you're going to need the definition of DataType, include "custom/datatype.h".


If custom::DataType is a type alias (i.e. typedef), you need to include the header. There isn't a way of forward-declaring type aliases: see this question & answers for related information.

Community
  • 1
  • 1
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • As I mentioned in the question, it is defined by a **typedef**. Its definition is actually based on some other internal data type used in custom (i.e. library) which is also in the namespace `custum`. So when I forward-declare it in the manner you suggest, I get this error when compiling: **"error C2371: 'custom::DataType': redefinition; different basic types"** – ilim Apr 27 '17 at 09:37
  • 1
    @ilim: I missed that apologies - edited my answer. You cannot really forward-declare a `typedef`. – Vittorio Romeo Apr 27 '17 at 09:42
1

If DataType is a class type or an enum with an underlying integer type, then you can forward declare it in action.h:

namespace custom {
  class DataType1;

  enum DataType2 : int; 
}

The downside is that it may break when you update the library. Well written libraries may have a header full of nothing other than forward declarations, which you may use, so you can look for those (example: iosfwd).

Otherwise, there is no recourse from including the header you are given by the library writer.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • I initially thought that, too, but unfortunately, as I noted in the question, it is defined by a **typedef**. Its definition is based on some other internal data type used in custom (i.e. library) which are also in the namespace `custum`. – ilim Apr 27 '17 at 09:32
  • @ilim - Then the last sentence in my answer applies, I'm afraid. – StoryTeller - Unslander Monica Apr 27 '17 at 09:33