8

BACKGROUND:optional

Since 2002 I've been slowly building my own Windows Native C++ library. And let's just say that I have jumped 150KLOC (reusable code) having everything I need and the kitchen sink in it (from most of the Windows API objectualized to a decent IMAP4 client implementation and the WordPress XMLRPC client for mass publishing... I do Affiliate Marketing and SEO Tools). It's not yet .NET but it ain't that far :)

The only 3rd party libraries used in it are ZLib, MySQL and SQLite. Everything else is built from scratch using the STL and/or Windows API. (I still have a PDF writer/reader to implement, IOCP all network things, and there's always room for more work...)

For the past 1.5 years I've been in a sustained effort of updating it for C++11. Move semantics where due, (explicit) bool operators, chained constructs and much more of what (MSVC's modest) C++11 brought us. Plus CRTP for chained parent/child calls, minimal use of virtuals, strict const-correctness. And succeeded.

Recently I've been really considering publishing it. It's a huge amount of work that I've only done for my own benefit and I assume there's still Windows C++ devs out there that could use such a thing. And to do that, went on to read C++ code practices and API/Library design guidelines. It was great! I nailed 80-85% of best coding practices myself. With a few things I'll address soon and one major question.

QUESTION

Currently the entire library is quite-templated and header only. That means all code is in the body of the classes. It's not very easy to manage but it's OK. I collapse code, use #pragma regions and nicely structure things.

BUT I'm VERY tempted, after reading several C++ library coding guidelines, to break it into .hpp + .inl files. Experimentally done so for a few classes and it does increase readability and makes it easier for others to deal with (even if it's a bit harder to write).

I know where everything (line of code, functionality) is at any given time. But other users might want to a quick overview of a classes declaration... and the definition ONLY if/when necessary (debugging).

  1. What are the accepted and/or preferred practices regarding splitting declarations from definitions. Would you rather have header only classes with in-body code or code separated from the function declaration?
  2. What are the current practices of other libraries? I've always written everything myself. Not that up to speed with how others do it. Except the 3 libraries mentioned above, I've yet to use other 3rd party code.

This is an important question for me because it's a one way road. I can't refactor it the other way later on so any feedback matters and is appreciated...

Thanks.

3
  • 3
    You probably mean "Background" rather than "Foreplay". Also, relax with the text formatting--it makes your question harder to read. I am tempted to drastically edit your question and remove the background section, it's not really relevant. Commented Aug 6, 2013 at 11:40
  • @M.Dudley Go for it! I deal with HTML a lot and SEO and I'm tempted to emphasize things. I wrote the Background to explain what the library is about, the compiler and such. Knowing it's Windows / MSVC turf might produce different answers compare to other compilers that are more C++11 aware.
    – CodeAngry
    Commented Aug 6, 2013 at 12:02
  • Today, with clangd used as a language server by IDEs for code modeling, splitting the implementations into .inl files and including them at the bottom of header files result in error messages because the header files are not self-contained. See github.com/clangd/clangd/issues/45 . I went down the "split into .inl files" road myself for my own open-source library, and am now faced with this clangd problem. I now have to decide if I want to move the implementations back into the class declarations, or at the bottom of the class declaration within the same .hpp file. Commented Apr 20, 2022 at 20:51

2 Answers 2

3

Your question is quite subjective (and might get closed for that), because there is no universally preferred practice when it comes to the use of in-class function definitions in C++.

One project that has a lot of large, header-only, libraries is Boost, and they don't seem to have a defined policy where the body of a method should go.

My personal preference when using a third-party library is (in order of preference)

  • To have separate, comprehensive, searchable API documentation. This documentation could be generated from the source (for example, with a tool like Doxygen), but I should not have to open the source files myself to read the documentation, or
  • Well-commented, well-organised class definitions, without the 'clutter' of in-class function bodies. Those implementation details can either come in the same file after the class(es), or in a separate file, or
  • Well-commented, well-organised class definitions with in-class function bodies.
2
  • I see a pattern... well commented :) That's important. Posted this on SO too and kind of answered myself^. But I'll keep it open here a bit longer just to see if I can get any other feedback. PS: I thought this site is especially designed for subjective talk (they say so in the FAQ, or at least that's what I understood).
    – CodeAngry
    Commented Aug 6, 2013 at 8:12
  • 1
    @CodeAngry: At P.SE, we accept a certain level of subjectivity, but not questions where every answer would be equally good. See also here: programmers.stackexchange.com/help/on-topic. Your question is on the edge of that distinction. Commented Aug 6, 2013 at 8:35
1

There is one major and some minor technical differences between body inside the class and outside of it.

The major difference is that method with body inside the class is implicitly considered declared inline. Not that compilers don't inline whatever they want anyway, but it affects the code generation somewhat. It is likely that if you overdo it with inline methods, the binary will be bigger and a little slower, so there is an argument for not writing larger bodies inside the class.

There is at least one minor difference; the only way to define a friend function (e.g. operator) for inner class of class template is with body inside the class. The friend modifier makes it not a member.

Not the answer you're looking for? Browse other questions tagged or ask your own question.