1

I'm programming in c++ for gta mods. Therefore I use ScriptHook V.

In types.h there is this:

typedef DWORD Void;
typedef DWORD Any;
typedef DWORD uint;
typedef DWORD Hash;
typedef int Entity;
typedef int Player;
typedef int FireId;
typedef int Ped;
typedef int Vehicle;
typedef int Cam;
typedef int CarGenerator;
typedef int Group;
typedef int Train;
typedef int Pickup;
typedef int Object;
typedef int Weapon;
typedef int Interior;
typedef int Blip;
typedef int Texture;
typedef int TextureDict;
typedef int CoverPoint;
typedef int Camera;
typedef int TaskSequence;
typedef int ColourIndex;
typedef int Sphere;
typedef int ScrHandle;

And the natives.h uses this types:

namespace PLAYER
{
static Ped GET_PLAYER_PED(Player player) { return invoke<Ped>    (0x43A66C31C68491C0, player); } // 0x43A66C31C68491C0 0x6E31E993
static Ped GET_PLAYER_PED_SCRIPT_INDEX(Player player) { return invoke<Ped>(0x50FAC3A3E030A6E1, player); } // 0x50FAC3A3E030A6E1 0x6AC64990
...

Now I wanted to make a Player class. But keep getting naming conflicts and I can't find a good solution to resolve them other then renaming my classes. Is there another way? My classes are in a namespace but it keeps conflicting.

stulleman
  • 163
  • 2
  • 14

2 Answers2

2

There are 2 possible solutions to this.

  1. Put your typedefs in their own namespace
  2. Use the scope resolution operator to differentiate

Both solutions require you to put your code in its own namespace, as it is these namespaces that we have to use to resolve the ambiguity.

In the following examples I've chosen to call the namespace you'd put your own code in MyCode - you're free to use any namespace you want, so long as it's unique.

Solution 1:

namespace Type 
{
    typedef int Player;
}
namespace MyCode
{
    class Player
    {
        Player(Type::Player id); // here you specify the namespace "Type" 
    };
}

Solution 2:

If your typedefs have to be in the global namespace, then the scope resolution operator can be used to differentiate them

typedef int Player;

namespace MyCode
{
    class Player
    {
        Player(::Player id); // here "::Player" refers to the typedef
    };
}

See this SO answer for more information on the scope resolution operator

Community
  • 1
  • 1
Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
  • Okay at least your second answer is working, but I'm trying to get the first one working too. When I add a namespace around the typedefs, I add a using namespace Types in natives.h. But then it says the name Player is ambigous – stulleman May 24 '16 at 15:35
  • @stulleman the first solution is the neater solution - so should be preferred. If it's not working for you then are you sure you're prefixing your typedefs with the namespace they're in? – Steve Lorimer May 24 '16 at 15:36
  • @stulleman re your edit in your comment about adding a `using namespace Types` that is definitely **not** the way to go, and that is the exact reason for the ambiguity. Remove the `using namespace Types` and refer to any `typedef` in your code as `Types::Player` etc – Steve Lorimer May 24 '16 at 15:37
  • @stulleman read [this](http://stackoverflow.com/a/15639578/955273) answer as to why the ambiguity is happening – Steve Lorimer May 24 '16 at 15:38
  • @SteveLorimer Solution 1 may be a no go. I looks like the header is not the OP's but that of the library. I would be very hesitant to change it. – NathanOliver May 24 '16 at 15:40
  • The problem with that is, that the natives.h is 5373 lines of Code. And the worst part is that it is constantly updated. So do you still see any possibility? – stulleman May 24 '16 at 15:40
  • @NathanOliver sounds like he is editing `natives.h` to add the namespace himself, and is then importing it into the global namespace? – Steve Lorimer May 24 '16 at 15:42
  • @stulleman Your other option is to not use duplicate names - you can prefix all of your classes with a mnemonic... `class MyPlayer`? – Steve Lorimer May 24 '16 at 15:43
  • @SteveLorimer Yeah not really sure. I like your second approach though. The OP should put his own code inside a namespace. – NathanOliver May 24 '16 at 15:43
  • @stulleman the point is that `using namespace Types` imports everything defined in that namespace into the global namespace, thereby completely defeating the point of namespaces – Steve Lorimer May 24 '16 at 15:43
  • Okay thanks for your help! The only possibility I see for me, correct me if im wrong, is that I use the scope resolution operator if don't want to change code from someone else? – stulleman May 24 '16 at 15:49
  • @stulleman *use the scope resolution operator* - yes, if the 3rd party types you have are in the global namespace, use the scope resolution operator. However, if the 3rd party types are in their own namespace, and you imported them into the global namespace (via `using namespace Types;`), then I would **not** do that, and I would qualify the types using their namespace (eg: `Person::Person(Types::Person)` - which is a `Person` constructor taking a `Types::Person` parameter) – Steve Lorimer May 24 '16 at 15:53
0

You probably meant typedef DWORD Uint; not typedef DWORD uint; as the latter might cause name conflict with a common typedef in Posix's sys/types.h.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
Eissa N.
  • 1,695
  • 11
  • 18