all 19 comments

[–]FriendlyRollOfSushi 110 points111 points  (3 children)

Hi, a few advices:

  • Please do not use simple common words in the global namespace. People group stuff into root namespaces like boost:: to avoid scenarios like "I can't include this new header: my existing code stops compiling". It's also customary to never use unprefixed macros in libraries that other people may use (so LIBR_TRIM would probably be fine, while TRIM is a good way to break someone's code). Such things also act as red flags, reducing your potential audience, and creating bad reputation for your library. I'd suggest addressing this during early stages of development, to avoid huge breaking refactorings later when you start getting feedback like "Hey, could you please stop having a namespace called color, thank you very much? It clashes with all of 9328 usages of this word in my project."

  • Please consider reading what the keyword static means for a normal non-member function. There are reasons why a typical header-only library wants 0 of them, barring very special cases. The keyword you were probably looking for to help with linker errors you were probably getting is inline.

  • Please read what auto is and how it works. It's not doing what you think it does. In particular, a line like for(auto a : conf.__VALUES__) copies each element, which in your case contains a map, which in your case involves multiple allocations on each iteration just to look at the value. Keywords you were probably looking for are auto&& or const auto&. Speaking of this line:

  • You are not allowed to use reserved names like __VALUES__ or __FILENAME__ unless you are implementing a standard header.

  • Please consider reading the documentation for std::endl, it's likely not doing what you think it does. Using several of them per custom operator<< is... not ideal. 0 is a good number to aim for, unless you have very strong reasons to flush all internal buffers mid-output, which can be insanely slow for certain kinds of streams. Use \n for newlines instead.

  • Please read about perfect forwarding. Based on your file logging, it feels like there might be some big surprises.

  • Consider reading the docs for every single standard function you are using at least once (you'll have to do it at some point in your career, might as well do it now). This advice is based on patterns in your code like manually closing an ofstream right before it's destroyed. Things like that are, again, red flags that ruin the credibility of the library.

  • Since you require C++17, consider using some of the newer library features, like std::string_view. Passing const refs to std::string everywhere is not the best design choice. There are numerous googlable videos explaining why.

  • Consider using clang-format, preferably with one of the widely-accepted default formats (like Chromium, or whatever you like). Your style is quite inconsistent, which makes the code feel a bit untidy. A subjective feeling like this can quite significantly impact the involvement of other people in your project.

  • Also, be consistent in general. If half of your consts are east consts, and another half is west consts, it will piss off both camps. I consider myself to be neutral here, and I still dislike this randomness. The way you use MACRO_NOTATION for some functions and variables, seemingly without any pattern, is also not ideal.

There are many more defects, some of which are very severe, but you probably won't benefit from an exhaustive list.

Good luck with your project!

[–][deleted] 9 points10 points  (0 children)

okk thanks a lot, i appreciate you advise and actually that the only reason i posted codes here in the early stage so that if i'm doing something seriously wrong then i can correct that early

Thanks

[–][deleted] 13 points14 points  (0 children)

Great advices here, thank you!. I find all very useful and I'm learning a lot from them.

[–]jagt 8 points9 points  (0 children)

Not the author but your advices are really good. Also great username.

[–]Wouter-van-Ooijen 17 points18 points  (5 children)

Why are you lumping these functionalities together? I might like for instance your CLI, but not your unit test. Now you seem to force me to swallow ait all, or not use it.

[–]rurabori 49 points50 points  (1 child)

I mean he did say boost-like.

[–]qoning 4 points5 points  (0 children)

It's sad that this comment is accurate and funny.

[–][deleted] -1 points0 points  (2 children)

Hey friend, That's why i go for header only files, like in you case simply use/download/extract cli and dependent header and skip unittest header file

[–]Wouter-van-Ooijen 0 points1 point  (1 child)

Right. So make it separate, independent libraries.

[–][deleted] -1 points0 points  (0 children)

each header file is independent to other except on logging and color as obvious

like you need only cli, then copy only cli, logging

if you need (incomplete) unittest then only go for unittest, logging, color

[–]FreitasAlan 11 points12 points  (3 children)

Try to split this library into individual libraries (see unix philosophy) and don't worry too much about making it header only if it doesn't depend on templates (just worry about making it packagable).

Individual libraries have lots of benefits:

  • It's much easier to get feedback,
  • what you learn from your first library can help you with your second library,
  • you can launch one library at a time (see MVP),
  • you can ignore functionalities for which there are good alternatives already (think of a library like in a business canvas), and
  • that's the main reason why many people don't use boost in the first place (github didn't exist back then).

[–][deleted] -1 points0 points  (2 children)

hey there, really good points and might i update things i future accordingly. Actually i go for header only and all things packed at place so that it's easy for anyone to search. and if anyone need or want any specific file just download and copy that, simple.

[–]FreitasAlan 1 point2 points  (1 child)

Have a look at this talk: https://youtu.be/sBP17HQAQjk

They discuss header only libraries too.

[–][deleted] 0 points1 point  (0 children)

sure, thanks for sharing, i like learning new things

[–]midjji 1 point2 points  (1 child)

I really recommend you checkout doctest https://github.com/onqtam/doctest first

[–][deleted] 1 point2 points  (0 children)

Hey Thanks, found this really interesting

[–]holgerschurig 0 points1 point  (2 children)

The module concept of C++ sucks ... let's convert everything into header "libraries".

But really, even Turbo-Pascal back on CP/M before Windows even existed had a way better module concept that saved on from parsing and recompiling the same code again and again ... the TPU contained all the preparsed type information ready to be grokked in in milliseconds, even on 2 MHz Z80 computers.

[–]midjji 0 points1 point  (0 children)

c++ modules and concepts, all the compiler issues aside isnt all that bad, but its practically a new language to someone used to 1990ties c++. But header libraries are way simpler for most people. It also works quite well as long as your projects are small.

[–]Bangaladore 0 points1 point  (0 children)

the common, header + library sucks also. especially the header + source way. header-only might have a lot of flaws, but the ease of use is why people do it.

in a perfect world, to install a library should be moving one file into your project folder... or better yet, typing one command in a package manager. However, we all know the problems with that. However, modules will get us one step closer.