Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper typedef location in C++ [closed]

Tags:

c++

typedef

I would like to ask the proper location of typedef in C++.

Version1 : typedef outside class

typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;

class MyData
{
public:
    MyData(){};
    ~MyData(){};
private:
    void addInfo(const StrIntPair &info)
    {
        infoVec.push_back(info);
    }
    StrIntPair info;
    StrIntPairVec infoVec;
};

Version2 : typedef inside class public

class MyData
{
public:
    MyData(){};
    ~MyData(){};
    typedef std::pair<std::string, int> StrIntPair;
    typedef std::vector<StrIntPair> StrIntPairVec;
private:
    void addInfo(const StrIntPair &info)
    {
        infoVec.push_back(info);
    }
    StrIntPair info;
    StrIntPairVec infoVec;
};

Version3 : typedef inside class private

class MyData
{
public:
    MyData(){};
    ~MyData(){};
private:
    typedef std::pair<std::string, int> StrIntPair;
    typedef std::vector<StrIntPair> StrIntPairVec;
    void addInfo(const StrIntPair &info)
    {
        infoVec.push_back(info);
    }
    StrIntPair info;
    StrIntPairVec infoVec;
};

Which version is the best practice?

like image 383
Zack Lee Avatar asked Aug 29 '18 08:08

Zack Lee


People also ask

Where do I put typedef?

First way is to typedef at the place-of-first-declaration. Second way is to typedef at each place-of-use, and make it only visible to that place-of-use (by putting it inside the class or method that uses it).

How is typedef used in C?

typedef is a reserved keyword in the programming languages C and C++. It is used to create an additional name (alias) for another data type, but does not create a new type, except in the obscure case of a qualified typedef of an array type where the typedef qualifiers are transferred to the array element type.

What is typedef declaration in C?

A typedef declaration is a declaration with typedef as the storage class. The declarator becomes a new type. You can use typedef declarations to construct shorter or more meaningful names for types already defined by C or for types that you have declared.

How does typedef struct work in C?

The C language contains the typedef keyword to allow users to provide alternative names for the primitive (e.g.,​ int) and user-defined​ (e.g struct) data types. Remember, this keyword adds a new name for some existing data type but does not create a new type.


2 Answers

This depends on where you use the type alias. I'd advice you to

  • Put them outside of the class if you use them across classes and/or functions and the meaning of the alias is not exclusively related to the class.
  • Define them as public class type aliases if client code outside of the class needs to access them (e.g. to initialize the object or to store an aliased return value of a member function) but the alias is related to the class. The alias then becomes a part of the class interface.
  • Define them as private class type aliases when you use them exclusively inside the class, e.g. some utility data structure that is annoying to type out all the time when passing it across member functions.

The compiler will only enforce scopes of aliases that are too narrow (e.g. you use a type alias defined in the private section of your class outside of that class) and won't complain if you choose an unnecessarily permissive scope (e.g. you publicly declare the alias, but use it only in the class implementation). Hence, strive to choose the narrowest scope possible, which is in line with hiding implementation details.

As a side note, you might want to consider declaring your type aliases with using StrIntPair = std::pair<std::string, int>;, see Item 9 in Effective Modern C++. This has no influence on the above, though.

like image 165
lubgr Avatar answered Oct 11 '22 19:10

lubgr


The question is about logical namespace of those names. With abstract naming like StrIntPair, StrIntPairVec and MyData there are no answers. Answers come when the things have meaning.

Lets take exactly same data structures but name them NickAndId, Friends and Player.

Now the question if to put NickAndId inside Player is about if it is specific to player. Can other entities like NonPlayerCharacter or Creature also have nickname and id expressed as same pair? Possibly. Then it should be outside.

Same question should be asked about Friends. Likely the NonPlayerCharacter and Creature can have nickname and id but do not have friends? Then it makes sense to put the type inside of Player as Player::Friends.

Finally, the types that are made private are meant only for usage by implementation details. That should be used when the name makes perfect sense in algorithms used inside of class but availability of those outside is unneeded or even worse, confusing. For example NonPlayerCharacter can react with some replicas to some states whose values are also internal to that NPC. Keeping that in sorted vector Reactions makes perfect sense inside of class. Access to ReplicaInState and Reactions from outside can be confusing.

like image 40
Öö Tiib Avatar answered Oct 11 '22 19:10

Öö Tiib