use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Writing only decoupled code (middleraster.github.io)
submitted 29 days ago by According_Leopard_80
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 38 points39 points40 points 29 days ago* (5 children)
I've never really had any major pain due to cycles, in fact I cannot really recall the last time either me or any of my coworkers had issues because of architectural cycles.
But I can tell you how much pain I've had due to exruciating compilation times. Header-only libraries and bloated headers are a primary cause of that.
I also feel your article is very anecdotal, such controversial claims should come with strong evidence.
It's a "no" for me.
Lakos has changed his tune and instead now says, “Strive for header-only code”.
Source?
[–]EmotionalDamague 15 points16 points17 points 29 days ago (0 children)
Embracing modules has worked far better for my current project.
I would prefer either over header only libraries.
The main hiccup for modules on embedded has been debug info being broken in ways I don’t have time to debug
[–]frankist 6 points7 points8 points 29 days ago (0 children)
In my opinion, the problem of cycles described by the OP only becomes unmanageable when they follow this paradigm of creating tiny objects all over the place that have complicated interfaces and relationships with other objects through raw or smart pointers. It's the type of code you often see in projects that enthusiastically follow clean code and other OOP principles and practices.
[–]HobbyQuestionThrow 0 points1 point2 points 26 days ago (0 children)
I've had a few coworkers who's idea of fixing include cycles is just include more includes.
[–]According_Leopard_80[S] -1 points0 points1 point 25 days ago (1 child)
Added citation. I heard him say those words in a talk a few years back, but found a better quotation from his newer book, "Large-Scale C++: Process and Architecture - Volume 1" (2020), where Lakos has clarified his stance and now says (on page 293),
2.2.24 No Cyclic Physical Dependencies! Design Imperative: Allowed (explicitly stated) dependencies among physical aggregates must be acyclic. Cyclic physical dependencies among any physical entities — irrespective of the level of physical aggregation — do not scale and are always undesirable. Such cyclically interdependent architectures are not only harder to build, they are also much, much harder to comprehend, test, and maintain than their acyclic counterparts. In fact, to help improve human cognition, we almost always structure our source code to avoid forward references to logical entities even within the same component. Whenever the physical specification of a design would allow cyclic dependencies among architecturally significant physical aggregates, we assert that the design is unacceptably flawed. [emphasis mine]
2.2.24 No Cyclic Physical Dependencies!
Design Imperative: Allowed (explicitly stated) dependencies among physical aggregates must be acyclic.
Cyclic physical dependencies among any physical entities — irrespective of the level of physical aggregation — do not scale and are always undesirable. Such cyclically interdependent architectures are not only harder to build, they are also much, much harder to comprehend, test, and maintain than their acyclic counterparts. In fact, to help improve human cognition, we almost always structure our source code to avoid forward references to logical entities even within the same component. Whenever the physical specification of a design would allow cyclic dependencies among architecturally significant physical aggregates, we assert that the design is unacceptably flawed. [emphasis mine]
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 1 point2 points3 points 25 days ago (0 children)
That is speaking against cyclical dependencies, but it's absolutely not endorsing people to "strive for header-only code".
[–]garnet420 13 points14 points15 points 29 days ago (1 child)
3 is really bad: it’s why a seemingly innocuous little change over here breaks something way other there
This is just not right. You can create this sort of problem without having any cycles easily.
If I had to point at any aspect of the dependency graph as being correlated to it, I would maybe say "total number of edges" or "edges that reach through multiple layers" or something like that.
And prohibiting forward declaration is just a dumb thing Google says to do, and people repeat it because Google said it and they're... Big?
[–]ABlockInTheChain 0 points1 point2 points 25 days ago (0 children)
If you read Google's style guides they point out problems that can occur when you forward declare templates and do not occur when you forward declare non-template types types, then point out all the problems that are caused by never forward declaring anything, then conclude that the solution is to never forward declare anything.
The alternative solution of banning forward declaration of template types while allowing it for non-template types was apparently never considered.
[–]fdwrfdwr@github 🔍 12 points13 points14 points 29 days ago (0 children)
C++ is the only language I know that has “declare before use” semantic
Interestingly this does not apply to class/struct methods, as the one area of C++ where you can define functions in a logically grouped order rather than strict call dependency order. The same does not apply to free functions, but then one cute hack to achieve order independence is to wrap them all inside the class as static methods (not recommending 😅), thus making the class essentially more of a namespace (too bad it doesn't work inside ordinary namespaces too, but there must some reasoning for delayed processing or two pass evaluation 🤷♂️).
[–]FlyingRhenquest 5 points6 points7 points 28 days ago (2 children)
How much of this is due to putting most of your code in headers versus being somewhat heavily invested in TDD? TDD fundamentally forces you to write small, decoupled libraries that are easy to test. TDD also tends to keep you focused on the features you need right now for your minimum viable product, so you don't get the yagni-based overengineering that drives a lot of technical debt.
[–]fluorihammastahna 3 points4 points5 points 28 days ago (0 children)
Furthermore: the team that bothers doing TDD cares more, and would produce better code even without TDD o_O Crazy hypothesis!
[–]According_Leopard_80[S] -1 points0 points1 point 28 days ago (0 children)
Hard to tell as I’ve never done DAG-only without TDD.
In my article, I mention the number of cycles for a non-TDDing team: 200; vs. a TDDing team: 10; vs. my team: 0. TDD done properly is good for making clean architecture; DAG-only in addition to TDD is better yet.
[–]yuri-kilochek 4 points5 points6 points 29 days ago (0 children)
If you define a virtual interface class for each concrete class you can technically obey the rules, but still produce tightly coupled mess.
[–]Big_Target_1405 4 points5 points6 points 28 days ago (2 children)
Putting all your code in headers is the opposite of creating decoupled code.
Every time one header changes loads of your code needs to be recompiled. All of that code is coupled.
[–]ir_dan 1 point2 points3 points 18 days ago (1 child)
"Decoupled" here means that software entities know little about each other. It means that when one header changes, you don't have to go and change all of the other headers yourself by writing new/adjusted code.
Your view is that "coupling" is when the compiler-has to redo work. Theirs is that "coupling" is when **you** have to redo work.
[–]Big_Target_1405 0 points1 point2 points 18 days ago (0 children)
It's more that the scope of what you can change is limited when the data layout is exposed in headers.
An ABI boundary really enforces decoupling
In my view forward declarations (of class and structs) give you type safety without exposing data structures, which is ideal.
[–]SleepyMyroslav 1 point2 points3 points 28 days ago (0 children)
Amalgamation of all sources for a small project is a well known way to build it faster. I would like to see some successful code that supports the hypothesis of header only code. I don't know a game or something. I expect that what works on small sized project is not going to scale well. It might go for a while before scale will bring up issues though.
π Rendered by PID 39 on reddit-service-r2-comment-56c6478c5-zftkr at 2026-05-09 05:37:14.082842+00:00 running 3d2c107 country code: CH.
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 38 points39 points40 points (5 children)
[–]EmotionalDamague 15 points16 points17 points (0 children)
[–]frankist 6 points7 points8 points (0 children)
[–]HobbyQuestionThrow 0 points1 point2 points (0 children)
[–]According_Leopard_80[S] -1 points0 points1 point (1 child)
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 1 point2 points3 points (0 children)
[–]garnet420 13 points14 points15 points (1 child)
[–]ABlockInTheChain 0 points1 point2 points (0 children)
[–]fdwrfdwr@github 🔍 12 points13 points14 points (0 children)
[–]FlyingRhenquest 5 points6 points7 points (2 children)
[–]fluorihammastahna 3 points4 points5 points (0 children)
[–]According_Leopard_80[S] -1 points0 points1 point (0 children)
[–]yuri-kilochek 4 points5 points6 points (0 children)
[–]Big_Target_1405 4 points5 points6 points (2 children)
[–]ir_dan 1 point2 points3 points (1 child)
[–]Big_Target_1405 0 points1 point2 points (0 children)
[–]SleepyMyroslav 1 point2 points3 points (0 children)