Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I actually prefer QT's approach, it allows you to annotate with extra properties if you want.

Back in games we'd usually use some DSL to generate all the boilerplate code for things like this(also including a whole bunch of editor-specific flags for signals/members).

Also, every time I bring in boost headers I watch compile times crater. C++ 11 or 14 is good enough at this point that I don't see a strong reason to use boost. I know of 2-3 projects that migrated from boost -> C++11 for that reason alone.



I’ve seen a lot of libraries, including parts of Boost, advertised as header-only. To me, this reflects the sad state of building cross-platform C++ dependencies; headers are the only things that library developers are confident that their users will be happy with. I’m very comfortable with doing build system maintenance, so the header-only “feature” seems like a straight-up drawback to me, killing my productivity with longer compile times.


> To me, this reflects the sad state of building cross-platform C++ dependencies; headers are the only things that library developers are confident that their users will be happy with.

...or that the code uses templates extensively (it's boost after all) thus everything must be placed in the same compilation unit so that the code can be generated at compile time.


Even with templates you could split of declaration and implementation. That would help with reducing compile times at the cost of having the user explicitly instantiate the used variations in some central location.


> Even with templates you could split of declaration and implementation.

No, you can't. The only case where the declaration of template functions/classes can be separated from definitions is in the rare cases where only a fixed and predetermined set of objects/values are used, thus enabling explicit instantiation.


And it is not possible to leave that choice to the user? Sometimes I wouldn't mind explicitly instantiating the few variations I need if it meant faster compile times for the remaining files.


> I’m very comfortable with doing build system maintenance, so the header-only “feature” seems like a straight-up drawback to me, killing my productivity with longer compile times.

on linux / macos it's fine, an apt-something away, but on windows anything else than header-only is a pain if you are providing a C++ library, because you may need :

- static and dynamic builds

- debug and release (changes the std:: ABI by default on windows)

- with static (/MT) and dynamic (/MD) runtimes (for whatever reason you can't link /MT with /MD code)

- x86 / amd64 (and more and more people are using windows on ARM increasing the demand for arm and aarch64).

So you need at least 2 * 2 * 2 * 4 (ie 32) distinct builds of your library if you want to cover all cases, and that's ONLY for vs 2015 and 2017 - older and newer versions break binary compatibility ; likewise for mingw / msys which needs its own set of libraries due to using itanium name mangling.


The only reason why this is a problem is because some people are doing this the hard way, manually creating Visual Studio project files for all 32 (or more) configurations. This is wasteful. There are better ways to do this.

You should probably be using tools that generate the Visual Studio projects for you. Some of these tools have been around for a long time, many of them are quite mature. You should be using GYP, CMake, Bazel, or something similar for building. These tools all work on Windows in addition to working on macOS and Linux. Hell, if these tools don’t work for you, then writing a Python script which spits out the Visual Studio projects is not out of the question either… I’ve done it, it’s not terrible!

If you are choosing to make a library header-only just because it’s too hard to build otherwise, well, my request is that you spend a day learning a build system which is not Visual Studio, and see if next time you make a library, you don’t restructure the code just to avoid learning how build systems work.


I mostly use CMake and even in perfect CMake projects it's still a pain to do (since you need all these build folders) - and most projects aren't "perfect" CMake projects, e.g. I'm using portaudio, SDL and their CMake scripts are fairly opinionated and need manual hacking to get required build configurations


I don’t mind modifying the CMake files for my dependencies, or when I’m using Bazel, writing the Bazel build files from scratch. I understand that not everyone feels this way, and it depends on how much labor you can spare for wrangling builds, but I still feel that this is less extreme / preferable to going header-only when header-only is not required for some other reason.

Yes, updating my Bazel build files for third-party dependencies creates extra toil when I upgrade versions. In my experience, this is a small amount of toil compared to the API changes a third-party will introduce (e.g. upgrading libfmt to 5.0 meant touching a hundred files), so I am willing to pay that price to get faster builds.

Or I’d put it this way:

- Most of my time is spent making changes, recompiling, and seeing the results. Small improvements here have a large positive impact on productivity, and header-only libraries make this worse.

- A small amount of my time is spent managing the build system and writing build scripts. Tasks like writing my own Bazel build script for a third-party dependency are not done often, maybe only when porting to a new platform or updating to a new version, so even though I spend extra time here, it is not burdensome.


But once you get CMake to build a VS project with, say, SDL and Lua already linked then it's still much easier than doing it through VS itself every time. The problem is getting it to do that, though.

I don't know why it can't be simpler but apparently it can't.


sure, but it's even more simple to just add a single path to the headers.

How many CMake config files export targets for debug and release windows libs for instance ?


It's not because of portability, it's more of a language design issue. Templates and metaprogramming simply doesn't play very well with pre-compiled libraries.


If it were just a template library, it would be fine. But networking libraries? JSON parsers? The problem is much wider. If libfmt can have a couple .cc files so can you.


Sure, that's why I called it a language design issue. Library users want generic and convenient interfaces (which arguably, boost does very well), there is just no way with modern C++ to keep the nice interfaces and at the same time put a significant amount of logic in a source file.

It is not surprising that boost choose convenience over tradition and fast compile speeds.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: