Proper typedef location in C++ [closed]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite












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?







share|improve this question












closed as primarily opinion-based by user463035818, Passer By, Karl Nicoll, Alan Birtles, BЈовић Aug 29 at 10:19


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.










  • 1




    All variants are right. It depends on where you want to use this aliases. Also I recommend to use using instead typedef
    – nikniknik2016
    Aug 29 at 8:06







  • 2




    smallest scope possible unless there is a reason to expose the typedefs publicly. However, asking for best practice is asking for opinions, hence offtopic
    – user463035818
    Aug 29 at 8:06







  • 1




    Same issue with variables, you want to limit its scope to whatever makes sense.
    – Passer By
    Aug 29 at 8:15














up vote
7
down vote

favorite












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?







share|improve this question












closed as primarily opinion-based by user463035818, Passer By, Karl Nicoll, Alan Birtles, BЈовић Aug 29 at 10:19


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.










  • 1




    All variants are right. It depends on where you want to use this aliases. Also I recommend to use using instead typedef
    – nikniknik2016
    Aug 29 at 8:06







  • 2




    smallest scope possible unless there is a reason to expose the typedefs publicly. However, asking for best practice is asking for opinions, hence offtopic
    – user463035818
    Aug 29 at 8:06







  • 1




    Same issue with variables, you want to limit its scope to whatever makes sense.
    – Passer By
    Aug 29 at 8:15












up vote
7
down vote

favorite









up vote
7
down vote

favorite











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?







share|improve this question












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?









share|improve this question











share|improve this question




share|improve this question










asked Aug 29 at 8:05









Zack Lee

469412




469412




closed as primarily opinion-based by user463035818, Passer By, Karl Nicoll, Alan Birtles, BЈовић Aug 29 at 10:19


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.






closed as primarily opinion-based by user463035818, Passer By, Karl Nicoll, Alan Birtles, BЈовић Aug 29 at 10:19


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.









  • 1




    All variants are right. It depends on where you want to use this aliases. Also I recommend to use using instead typedef
    – nikniknik2016
    Aug 29 at 8:06







  • 2




    smallest scope possible unless there is a reason to expose the typedefs publicly. However, asking for best practice is asking for opinions, hence offtopic
    – user463035818
    Aug 29 at 8:06







  • 1




    Same issue with variables, you want to limit its scope to whatever makes sense.
    – Passer By
    Aug 29 at 8:15












  • 1




    All variants are right. It depends on where you want to use this aliases. Also I recommend to use using instead typedef
    – nikniknik2016
    Aug 29 at 8:06







  • 2




    smallest scope possible unless there is a reason to expose the typedefs publicly. However, asking for best practice is asking for opinions, hence offtopic
    – user463035818
    Aug 29 at 8:06







  • 1




    Same issue with variables, you want to limit its scope to whatever makes sense.
    – Passer By
    Aug 29 at 8:15







1




1




All variants are right. It depends on where you want to use this aliases. Also I recommend to use using instead typedef
– nikniknik2016
Aug 29 at 8:06





All variants are right. It depends on where you want to use this aliases. Also I recommend to use using instead typedef
– nikniknik2016
Aug 29 at 8:06





2




2




smallest scope possible unless there is a reason to expose the typedefs publicly. However, asking for best practice is asking for opinions, hence offtopic
– user463035818
Aug 29 at 8:06





smallest scope possible unless there is a reason to expose the typedefs publicly. However, asking for best practice is asking for opinions, hence offtopic
– user463035818
Aug 29 at 8:06





1




1




Same issue with variables, you want to limit its scope to whatever makes sense.
– Passer By
Aug 29 at 8:15




Same issue with variables, you want to limit its scope to whatever makes sense.
– Passer By
Aug 29 at 8:15












2 Answers
2






active

oldest

votes

















up vote
12
down vote













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.






share|improve this answer






















  • And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
    – spectras
    Aug 29 at 8:20






  • 2




    @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
    – user463035818
    Aug 29 at 8:25










  • i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
    – user463035818
    Aug 29 at 8:28

















up vote
1
down vote













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.






share|improve this answer





























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    12
    down vote













    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.






    share|improve this answer






















    • And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
      – spectras
      Aug 29 at 8:20






    • 2




      @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
      – user463035818
      Aug 29 at 8:25










    • i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
      – user463035818
      Aug 29 at 8:28














    up vote
    12
    down vote













    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.






    share|improve this answer






















    • And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
      – spectras
      Aug 29 at 8:20






    • 2




      @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
      – user463035818
      Aug 29 at 8:25










    • i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
      – user463035818
      Aug 29 at 8:28












    up vote
    12
    down vote










    up vote
    12
    down vote









    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.






    share|improve this answer














    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 29 at 8:45

























    answered Aug 29 at 8:12









    lubgr

    5,9951339




    5,9951339











    • And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
      – spectras
      Aug 29 at 8:20






    • 2




      @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
      – user463035818
      Aug 29 at 8:25










    • i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
      – user463035818
      Aug 29 at 8:28
















    • And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
      – spectras
      Aug 29 at 8:20






    • 2




      @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
      – user463035818
      Aug 29 at 8:25










    • i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
      – user463035818
      Aug 29 at 8:28















    And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
    – spectras
    Aug 29 at 8:20




    And remember that if it's public, it becomes part of your class interface. It should have a proper name, and changing the type later on might have repercussions. You might consider wrapping the type to expose a controlled subset of its interface.
    – spectras
    Aug 29 at 8:20




    2




    2




    @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
    – user463035818
    Aug 29 at 8:25




    @sepctras one could also argue the reverse, eg if you use std::vector<??>::value_type in your code instead of ?? then the actual type can change without the need for changing a single line of code
    – user463035818
    Aug 29 at 8:25












    i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
    – user463035818
    Aug 29 at 8:28




    i like your point of compiler only complaining about too permissive scope. Thats a very concise argument for choosing the narrowest scope possible.
    – user463035818
    Aug 29 at 8:28












    up vote
    1
    down vote













    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.






    share|improve this answer


























      up vote
      1
      down vote













      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.






      share|improve this answer
























        up vote
        1
        down vote










        up vote
        1
        down vote









        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.






        share|improve this answer














        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Aug 29 at 9:10

























        answered Aug 29 at 8:53









        Öö Tiib

        6,8611829




        6,8611829












            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            Installing NextGIS Connect into QGIS 3?

            One-line joke