Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ wrapping types for semantic

Tags:

c++

It has been a long time since my last use of c++, coming back from java and python, I have a question about good practices on c++:

I wanted to keep a semantic code about some really simple objects, let's say we have objects Tag and File, which both only are std::string and a class TagManager which contains several functions using Tags and Files.

My question is, is it better to create a custom type representing these trivial objects or to use them directly for what they are?

To be more specific I have could have one of those definitions for a function:

TagIterable myFunction(Tag tag, File file);
std::vector<Tag> myFunction(Tag tag, File file);
std::vector<std::string> myFunction(std::string tag, std::string file);

I prefer the first solution because I like to keep a semantic code, on the other hand doing it requires the user to check what these types are, so it reduce the simplicity of use.

I also read on another question (Thou shalt not inherit from std::vector) 'Do not produce new entities just to make something to look better.'

So what do you do in such situation; what does the C++ philosophy recommend to do?

like image 948
aveuiller Avatar asked Nov 24 '13 11:11

aveuiller


1 Answers

I usually use typedefs in such cases:

  • Even though typedefs don't introduce new types or nasty derivatives of std::vector<> themselves, the aliases may still be possibly annoying indirections for those using your code.
  • On the other hand, they could be exposed and documented well (provide an example), so that everybody uses them from start.
  • They help to avoid build breakers, in case the type needs to be changed (provided, that special std::string features aren't used or are provided in the replacement, in your specific case).
  • So, if required, a typedef could later be changed to alias a new class with extra properties and functions, or just for type safety.
  • They allow easy tracking of usage locations, as well as refactoring in most IDEs.
namespace mylib
{
    typedef std::string Tag; //perhaps 'TagType' or 'tag_type', to follow the naming
                             //conventions of the standard library, e.g.
                             //std::vector::value_type
    typedef std::string File;//Same as above, 'FileName' might be more appropriate

    typedef std::vector<Tag> TagIterable;
                             //Could be named 'TagContainer',
                             //`TagVector` or `TagSet` when using std::set,
                             //to match the terminology of C++

    TagIterable myFunction(const Tag& tag,const File& file);
                             //One may use references to const here,
                             //to explicitly avoid unnecessary copies

};
like image 122
Sam Avatar answered Oct 24 '22 13:10

Sam