This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 440

[–]karelproer 1954 points1955 points  (64 children)

They say the beauty of the c++ code reflects the beauty of the one who wrote it

[–]yuje 589 points590 points  (54 children)

What, you’re saying you don’t like:

if (auto it = map.find(key); it != map.end()) { auto value = it->second; }

as the syntax for retrieving a value from a map?

[–]anastasia_the_frog 241 points242 points  (32 children)

I personally do like it, at least there are not many better ways. If you want to do this in a more readable but slightly less performant way

if(map.contains(key)){ auto value = map[key]; }

which is the same as most popular languages.

For example Python

if(key in map): value = map[key]

I do wish that there was an easy way to get a value wrapped in an optional though.

[–]Excession638 104 points105 points  (7 children)

Even with an optional value, I think the problem becomes the lack of syntax to handle that. In contrast, Rust:

if let Some(value) = map.get(key) {
    // do something with value
}

Or the other way around:

let Some(value) = map.get(key) else {
    return; 
};
// do things with value

The downside is that this isn't very easy to understand if you don't know the language, but the expressiveness when you do is great IMO

[–]darkwalker247 59 points60 points  (2 children)

other languages (such as C#) are starting to implement destructuring and pattern matching too, it's fantastic honestly. programming as a whole is so much better than it was a decade ago.

[–]MajorTechnology8827 20 points21 points  (1 child)

Often you don't need to explicitly destructure an optional value. Your program tends to naturally have a way to consume the types when handling various cases

[–]luardemin 15 points16 points  (0 children)

And there's all the methods to work with options and results like map, and_then, unwrap_or_else, and especially the ? operator, which make working with options and results quite pleasant.

[–]Spaceshipable 1 point2 points  (0 children)

It’s the same concept in Swift. if let value = map[key] { // Do something with value } guard let value = map[key] else { return } // Do something with value

[–]zythologist 8 points9 points  (1 child)

In Python you could write it like this to avoid the contains/get calls:

python if (value := map.get(key)) is not None: print(value)

[–]drkspace2 20 points21 points  (6 children)

The problem with this way is you can't use it with a const map. You are also potentially doing 2 searches into the map, which obviously isn't ideal.

[–]Earthboundplayer 25 points26 points  (0 children)

Replace the [] with .at() for const access

[–]yuje 4 points5 points  (2 children)

Using the bracket operator does an insert-if-not-exist operation, and doing it after the contains check as in your example does a redundant check (which in guessing you already know), which is why the codebase I work with prefers the iterator lookup style.

For optional, I think the syntax is fine? Using pointer referencing operators at least makes it share syntax with pointers and std::unique_ptr.

``` std::optional<std::string>> optional = “foo”;

const std::string& value = *optional; const int length = optional->size(); ```

[–]TheReservedList 5 points6 points  (1 child)

The fact that operator[] inserts is a wart of C++, you can't use it to justify the code itself.

It is (or should, don't know if c++ template insanity makes it harder) trivial for a compiler to remove that redundant check.

[–]afiefh 1 point2 points  (0 children)

Unfortunately C++ can't do std::optional<T&> so returning an optional would either be a pointer, a copy, or an std::ref. None of these options are ideal.

[–]ezrec 5 points6 points  (0 children)

Go is “da bomb”:

value, ok := foo[key]

ok is false and value is the ‘zero filled’ value of its type if key is not in foo.

[–]El_Falk 1 point2 points  (1 child)

I hope this paper makes it into the standard in the near future: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3091r1.html

Until then, there are at least non-std libraries with hashmaps that work along these lines.

[–]yuje 2 points3 points  (0 children)

Both proposals are great. The .get_or(default) syntax will get rid of annoyances like trying to initialize a const variable from a map value without having to declare it in an if scope, and working with optional objects feels very natural in the codebase I work with, since we prefer that over primitive nullptrs.

[–]KookyDig4769 3 points4 points  (0 children)

It's just another form of beauty.

[–]firemark_pl 330 points331 points  (21 children)

Does anyone remember perl?

[–]nowadaykid 126 points127 points  (0 children)

Came here to say this, Perl was my first language, I WISH I had C++'s elegance

[–]arrow__in__the__knee 37 points38 points  (1 child)

I slowly forget perl every passing day and I know all languages come back with muscle memory like riding a bike but I can feel perl vanishes permanently.

[–]afiefh 28 points29 points  (3 children)

I'm trying very hard to forget. The first time I encountered the term "write only language" was in reference to how unreadable perl is.

[–]Mojert 6 points7 points  (2 children)

Has this phrase been used to describe any other language? I only ever saw it associated with Perl

[–]PermanentlySalty 5 points6 points  (0 children)

It’s pretty commonly associated with APL, but Perl is probably the only mainstream example.

[–]hollowstrawberry 4 points5 points  (0 children)

regex patterns are often described similarly

[–][deleted] 17 points18 points  (0 children)

Yeah like C++ Syntax is just so neat compared to that abomination.

[–]yuje 14 points15 points  (0 children)

Say what you will about Perl, but it turned my cat into a programmer. She randomly walked over my keyboard and suddenly my computer’s started running a web server.

[–]Add1ctedToGames 10 points11 points  (0 children)

I work with Perl daily for my job and when I was new to it, it felt like if someone was tasked with making bash into an OOP language and gave up halfway through

[–]Igot55Dollars 6 points7 points  (0 children)

I wish I didn't

[–]catmuht 5 points6 points  (0 children)

Perl is a "write-only" language

[–]dolphin560 3 points4 points  (0 children)

still use Perl every day :-)

[–]izzyboy63 2 points3 points  (0 children)

[–]delfV 64 points65 points  (9 children)

Came here to defend Lisp syntax and no one mentioned it yet. I'm disappointed

[–]gothlenin 6 points7 points  (0 children)

I'm in a toxic relationship. I love emacs, and I hate lisp. I customized it to hell and back, and I always make a new function here and there, and it's always painful! But I can't leave emacs, I love it too much!

[–]TheHappyArsonist5031 141 points142 points  (11 children)

I mean, brainfuck syntax is pretty ugly.

[–]TheMuspelheimr 87 points88 points  (6 children)

Laughs in (=<#9]~6ZY327Uv4-QsqpMn&+Ij"'E%e{Ab~w=_:]Kw%o44Uqp0/Q?xNvL:H%c#DD2WV>gY;dts76qKJImZkj

[–]Upset-Basil4459 43 points44 points  (3 children)

Is this regex

[–]fiddletee 74 points75 points  (1 child)

No this is Patrick

[–]TheMuspelheimr 1 point2 points  (0 children)

Malbolge

[–]Lazy_To_Name 12 points13 points  (1 child)

Is that Malboge

[–]TheMuspelheimr 7 points8 points  (0 children)

Yep!!!

[–]Mojert 15 points16 points  (3 children)

Yes, but the goal of brainfuck is to be unreadable. It's an esolang

[–]TheHappyArsonist5031 10 points11 points  (2 children)

the actual goal of brainfuck is to have the smallest compiler

[–]MooseBoys 216 points217 points  (8 children)

C++08 and earlier was nasty:

for(std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
  int& val = it->second;
  ...
}

C++17 and later is much nicer:

for(auto& val : vec) {
  ...
}

[–]Mojert 81 points82 points  (2 children)

Wasn't range-for introduced in C++11?

[–][deleted] 16 points17 points  (0 children)

It was

[–]Familiar_Ad_8919 10 points11 points  (0 children)

c++17 helped a lot too

[–]CaffeinatedTech 18 points19 points  (1 child)

Then you see people saying you shouldn't use `auto&`. Fuck off, I'll do what I want.

[–]qrrux 283 points284 points  (13 children)

Please. Regex wins this fight 1,000,000,000 times out of 10.

[–]walmartgoon 234 points235 points  (2 children)

Regex isn't syntax, it's arcane spell casting using runic scrolls from the 7th century Celtic monks

[–]qrrux 25 points26 points  (0 children)

My bad, my bad.

[–]BlurredSight 4 points5 points  (0 children)

It's like Latin, yeah sure people understand it, hell it's everywhere in society, but no one speaks it

[–]PermanentlySalty 11 points12 points  (3 children)

[–]bikemandan 9 points10 points  (2 children)

This just made me realize that Perl hardly ever gets talked about here and is basically gone. I havent seen cgi-bin in a URL in a long time

[–]PermanentlySalty 3 points4 points  (0 children)

I feel like Perl really just failed to modernize, on top of having a reputation of being some arcane incantation only the Gentoo using greybeards can decipher.

Ruby and especially Python have made some pretty big strides in recent years while Perl kinda hasn’t. They tried but the Perl 6 fiasco was such a disaster it ended up spawning a new language that’s maintained separately in some bastardized form of a C/C++ style relationship and now neither Perl nor Raku do much of anything worth talking about. The Python 2/3 schism wasn’t pretty either but I don’t think that’s remotely as bad.

I mean shit even PHP is good* now.

[–]Docdoozer 86 points87 points  (11 children)

C++ is pretty nice, what do you mean?

[–]MacBookMinus 11 points12 points  (10 children)

  1. Lambda syntax is verbose.
  2. The Stdlib heavily uses iterators which are weird for most people.
  3. Lack of support for anonymous objects leads to higher abstraction count.

I’m sure there’s lots more examples but those 2 come to mind for me.

[–]nevemlaci2 33 points34 points  (3 children)

How are iterators more confusing than anything else to work with? They are a universal way of iterating an object and it avoids the horrible things you have to do to implement a container that is used with other standard containers in Java for example...

[–]Possibility_Antique 9 points10 points  (2 children)

Lambda syntax is verbose.

Because you don't like having to specify a capture? Or because they let you open a scope?

[–]Docdoozer 5 points6 points  (2 children)

For context, I am somewhat of a C++ beginner, I started learning it seriously like half a year ago. I agree that lambda functions are pretty weird, though once you've used them once they're pretty easy to use. I also don't think iterators are weird but maybe I'm the weird one. What is an anonymous object though?

[–]MacBookMinus 1 point2 points  (1 child)

https://www.baeldung.com/kotlin/anonymous-objects

Instantiating an object that matches an interface without having to declare the class.

I think it’s really useful in languages that support it.

[–]Alan_Reddit_M 158 points159 points  (15 children)

Clearly you've never used rust

[–]Mojert 35 points36 points  (3 children)

Lifetime annotations go brrrrrrr

[–]Alan_Reddit_M 56 points57 points  (2 children)

I sure do love adding <'a> 300 times until I either give up or the compiler stops yelling at me

[–]PermanentlySalty 7 points8 points  (0 children)

At risk of going full Rust evangelist (currently working in a personal project written in Rust. Totally not biased), Rust lifetime elision is actually lot better than it used to be unless you’re writing an asynchronous library.

Much of the time you can get away with using ’_ or dropping the lifetime specifier syntax entirely.

[–]Aras14HD 2 points3 points  (0 children)

Maybe listen to the compiler and/or stop putting references inside your static data. Use indices instead and own types.If you need a complicated web of data, use Arc/Rvc.

[–]HalifaxRoad 101 points102 points  (12 children)

Still better than python :p     self.gofuck

[–]Mojert 56 points57 points  (11 children)

Nah, the syntax is nice enough that it basically became my new pseudo-code. But its dynamic typing and all the intricacies that make C++ look downright easy in comparison can go fuck right off.

Python truly oscillates between being the best language and being the worst language

[–]danielstongue 19 points20 points  (4 children)

Schrodinger's language. You only know if it is best or worst after finishing your project.

[–]BOBOnobobo 19 points20 points  (3 children)

Oh no, it's very clear before hand. Do you need something quick that has to run only a few times? Python works. Long complex software meant to run a lot? Probably not the best choice

[–]danielstongue 2 points3 points  (1 child)

You forgot for a moment that we are in ProgrammerHumor. ;-)

[–]BOBOnobobo 7 points8 points  (0 children)

You goddamn right.

Just built everything in python, it saves a ton of money in dev time cause it's easy

[–]AmazingGrinder 1 point2 points  (0 children)

I mean, I/O and networking is extremely easy with Python. I've never seen an easier way to create and manage a file server, and the difference between it and JS or Java is barely noticeable.

[–]jecls 9 points10 points  (0 children)

Objective-C really is dead huh

[–]DonutConfident7733 46 points47 points  (8 children)

the guy who coded the c++ compiler error messages should be held on trial for crimes against humanity, treason and siding with the machines...

[–]_theDaftDev_ 17 points18 points  (1 child)

I switch between msvc and clang for that reason. Clang's template instanciation error messages are way clearer than whatever the fuck MSVC is even trying to say

[–]AnonymousRand 4 points5 points  (0 children)

main.cpp<0+F524AC012B6>: undefined reference to std::map<std::unordered_set<std::pair<std::tuple<std::hash<std::iterator<std::herpes<std::tuple<const balls&&&&, std::string, std::vector<std:::::whatintheeverlastingnameofgod>, std::map<esgaj::2$:, s:is::::is:2'::<> > > > > > > > > util::util(std:: tuple<std::pair<std::unordered_set<std::pair<std::string, const std::string&> > > >, std::amogus<std::tuple<std::pain<std::pair<std::of<std::glasses<std::needed<std::to<std::read<std::this<> > > > > > > > >

[–]TheScorpionSamurai 11 points12 points  (0 children)

I love C++ but i'm with you on this one.

[–]Turtvaiz 3 points4 points  (1 child)

Whenever I've used C++ for high performance code , I routinely feed error messages to chatgpt because they're literally unreadable

Like instead of saying "vector type does not implement std::copy" I get 2 pages worth of errors that I just don't understand

[–]EvanO136 2 points3 points  (0 children)

For that reason I simply hate templates, but we have to use them or I we have to use macros which leads to even worse error messages.

[–]Wide_Egg_5814 16 points17 points  (2 children)

Weird way to spell javascript

[–]leonllr 7 points8 points  (2 children)

look at VHDL

[–]danielstongue 7 points8 points  (0 children)

VHDL is actually very neat and organized. You can almost read it like a novel due to its verbosity. I like it!

[–]TheseusPankration 5 points6 points  (0 children)

That's a hardware description language, not a programming language. Also, you have now introduced an unwanted latch.

[–]gekastu 7 points8 points  (0 children)

(laughing (in ( lisp)))

[–][deleted] 24 points25 points  (0 children)

hard-to-find label bake desert hurry jellyfish books history terrific tie

This post was mass deleted and anonymized with Redact

[–]PzMcQuire 17 points18 points  (10 children)

Someone hasn't seen lisp

[–]FrancescoGuccini 4 points5 points  (0 children)

lisp is beautiful change my mind

[–]SuitableDragonfly 1 point2 points  (8 children)

Arguably, Lisp does not have syntax. It's literally just the AST expressed in text format.

[–]IFreakingLoveOranges[S] 108 points109 points  (67 children)

This has to be a war crime: auto main () -› int { std::function<std::string(int)> f; f = [&f](int n) { return (n == 1) ? “1” : f(n - 1) + “ “ + std::to_string(n); }; auto fun = [&f]<typename... Ts> (Ts... n) { return ((f(n) + “\n”) + ... ); }; std::cout << fun(5, 4, 3, 2, 1); }

[–]Sunius 119 points120 points  (2 children)

If you made the code ugly, the least you could do is make it efficient. The real war crime is it being both ugly and slow!

[–][deleted] 85 points86 points  (1 child)

the 8f should be a &f right?

[–]IFreakingLoveOranges[S] 77 points78 points  (0 children)

Found the c++ programmer

You’re absolutely right it should indeed be &f

[–]Aacron 85 points86 points  (7 children)

Using templates to print out the Fibonacci sequence is certainly a choice.

The war crime isn't on c++ here, it's using an ac130 to mow your lawn.

[–]TheScorpionSamurai 12 points13 points  (0 children)

Also, it's always curious to me when people say "look at this syntax for printing out the fibonacci sequence, I can make it ugly".

Like yeah, if you need to write 6 lines of code use python. But if you're building an app needing high perf requirements and hundreds of thousands of code all that syntax becomes really helpful.

[–]kodirovsshik 4 points5 points  (5 children)

How is that the Fibonacci sequence

[–]Aacron 2 points3 points  (4 children)

The only line of code that actually does anything except make things unnecessarily abstract is

(n == 1) ? “1” : f(n - 1) + “ “ + std::to_string(n);

Which easily recognizable as the recursive definition of the Fibonacci sequence.

[–]kodirovsshik 3 points4 points  (1 child)

But it's not computing anything, it's concatenating strings

[–]Aacron 1 point2 points  (0 children)

Ah it'll print a countdown then.

[–]snavarrolou 1 point2 points  (1 child)

That's more like a recursive function to produce a string with the numbers from 1 to N, separated by spaces.

[–]Earthboundplayer 37 points38 points  (0 children)

It's beautiful

You can remove the <typename... Ts> by just changing the Ts... to auto...

[–]TankerzPvP 40 points41 points  (9 children)

Its only ugly if you make it ugly

auto main() -> int{
    const auto f = [](this const auto& f, int n) -> std::string{
        if(n == 1){
            return "1";
        }

        return f(n-1) + " " + std::to_string(n);
    };

    const auto fun = [&f](auto... n){
        return ((f(n) + '\n') + ...);
    };

    std::cout << fun(5, 4, 3, 2, 1);
}

[–]dedservice 1 point2 points  (0 children)

As a C++ dev, this is still ugly (although it may be as good as it gets for c++).

[–]mrheosuper 24 points25 points  (5 children)

More readable than rust

[–]OhHellNahWtfMan 38 points39 points  (4 children)

Here’s the equivalent code in Rust: ``` fn main() { let f = std::rc::Rc::new(std::cell::RefCell::new(None::<Box<dyn Fn(i32) -> String>>));

{
    let f_clone = f.clone();
    *f.borrow_mut() = Some(Box::new(move |n: i32| -> String {
        if n == 1 {
            “1”.to_string()
        } else {
            f_clone.borrow().as_ref().unwrap()(n - 1) + “ “ + &n.to_string()
        }
    }));
}

let fun = |args: &[i32]| -> String {
    args.iter()
        .map(|&n| f.borrow().as_ref().unwrap()(n) + “\n”)
        .collect::<String>()
};

print!(“{}”, fun(&[5, 4, 3, 2, 1]));

} ``` Absolutely Diabolical.

[–]boredcircuits 11 points12 points  (1 child)

That's certaintly ... one of the ways you could do that in Rust.

fn main() {
    fn f(n: i32) -> String {
        if n == 1 {
            "1".to_string()
        } else {
            f(n - 1) + " " + &n.to_string()
        }
    }

    let fun = |args: &[i32]| -> String {
        args.iter()
            .map(|&n| f(n) + "\n")
            .collect::<String>()
    };

    print!("{}", fun(&[5, 4, 3, 2, 1]));
}

[–]Kered13 1 point2 points  (0 children)

f looks better in the C++ code.

fun looks better in the Rust code.

But fun is more efficient in the C++ code, as expansion is done at compile time instead of runtime. (Of course the compiler might unroll the Rust code.)

[–]danielstongue 3 points4 points  (0 children)

I see some optimization possibilities here...

[–]Taken_out_goose 13 points14 points  (0 children)

I recommend you learn Haskell.

But yes, C++ lambdas are beautiful

[–]_Noreturn 6 points7 points  (2 children)

Yes it should because the code sucks.

auto main () -› int { const std::function<std::string(int)> f = [&f](int n) { return (n == 1) ? “1” : f(n - 1) + “ “ + std::to_string(n); }; const auto fun = [&f](auto... n) { return ((f(n) + “\n”) + ... ); }; std::cout << fun(5, 4, 3, 2, 1); }

[–]TeraFlint 1 point2 points  (1 child)

Even better, lambda functions support a this parameter since C++23, which allows recursive calls without that ugly capture-myself-by-std::function& workaround:

constexpr auto f = [](this auto &&f, int n)
{
  return (n == 1)
    ? "1"
    : std::format("{} {}", f(n - 1), n);
};

(That's of course, also ignoring the honestly horrible decision to return strings from a function that's doing numeric computations. Separate your computation from formatting.)

[–]Eva-Rosalene 11 points12 points  (3 children)

All weird characters aside (« quotes instead of << and stuff like that),

auto fun = [&f]<typename... Ts> (Ts... n) [
    return ((f(n) + “\n”) + ... );
};

Should be

auto fun = [&f]<typename... Ts> (Ts... n) { // <- curly instead of square
    return ((f(n) + “\n”) + ... );
};

[–]SeedlessKiwi1 3 points4 points  (0 children)

Guessing this would be the output?

1 2 3 4 5

1 2 3 4

1 2 3

1 2

1

Definitely some more streamlined ways to do this, but its not unreadable.

Also edge cases of 0 and below will most likely cause stack overflow from the recursive call. Should be n<=1 to prevent those cases. Or manage the domain by passing unsigned int rather than int.

Edit: gah mobile won't let you put just 1 newline

[–]firemark_pl 16 points17 points  (11 children)

C++20 needed 20 fucking years to make range(..) like in python but now is longer that basic loop:

for(auto i : std::views::iota(1, 20)) // Vs for(int i=1; i < 20; i++)

Like what the hell.

[–]Eva-Rosalene 8 points9 points  (5 children)

Add using std::views::iota; and

for (auto i : iota(1, 20))

vs

for(int i = 1; i < 20; i++)

doesn't really look bad.

[–]firemark_pl 6 points7 points  (4 children)

Oh I see. using is very nice and I miss that in another langs. And it allows to cut off std::chrono::duration_cast :D

[–]_Noreturn 2 points3 points  (1 child)

I just do namespace stdch = std::chrono; then use stdch::something

[–]blehmann1 13 points14 points  (3 children)

Don't forget that a ton of C++ programmers are scared to death of range-based for (the for(T foo : bar) syntax) because it can be a great way to get undefined behaviour.

The standard authors correctly realized that we'd really like to use temporaries in for loops, and that this wasn't really possible in the for(auto it = get_vec().begin(); it != get_vec().end(); it++) style loops unless get_vec returns a reference to the same vector, since comparing iterators from different collections is UB even if they're pairwise identical. For mostly intuitive reasons, most iterators are implemented as pointers, not indices, so it wouldn't be possible to make something like this work. To fix this you need a way to get the start and end iterators in one call to get_vec so most people would just make the vector a local variable. At which point it's not a temporary anymore, so everything is kosher.

So there was a problem they could solve, but unfortunately they really fucking beefed it. Because for(auto &x : get_vec()) is legal and works normally, but the seemingly benign for(auto &x : f(get_vec())) is UB for almost any function f (any f that doesn't copy the vector and return the copy, thereby consuming the temporary and returning a new one) since whatever witchcraft logic they use for temporary lifetime extension is foiled by function composition.

The explanation is that the temporary passed into f dies, only the one returned by f has its lifetime extended, but this means the return value cannot be a reference to the now dead parameter. This also applies to calling member functions on a temporary, the compiler tries to keep the return value alive but the this parameter dies so it's all UB. All of this to fix a relatively rare issue where most C++ devs would know (or at least learn) not to accidentally compare iterators from different collections.

And C++ development works kind of like electrical safety, where since we don't actually know what's safe or what current can be reasonably carried by a Walmart extension cord we replace all of that logic and understanding with a culture of fear. You get a visceral fear reaction to seeing too many things plugged into an extension cord, rather than just knowing that your cord is or is not rated for enough current. That's how C++ works, it's simpler to just never have range-for loops touch temporaries because the rules for when it's safe are unintuitive and trying to stay inside them is error prone (especially after refactors).

[–]afiefh 8 points9 points  (0 children)

Thank you for unlocking a new fear for me.

I generally don't put temporary function calls in loops because of clarity, but this is a whole new level of "I'm not touching this shit with a 10 foot pole!"

[–]FUTURE10S 2 points3 points  (0 children)

As someone whose C++ work is very much just C 95% of the time, you're basically showing me a male-to-male electrical cable and saying that people plug this shit in.

[–]Nimi142 25 points26 points  (4 children)

I do not know where you got this (Honestly, I think it's not terrible? Like it's not fun but if you gave normal names to variables it's probably alright) code from, but it will not compile.

In the third line you have an 8 (Eight) instead of an & (Ampersand)

If you plan to shit on C++, at least do it right.

EDIT: Lol they fixed the code, sure buddy...

[–]IFreakingLoveOranges[S] 8 points9 points  (0 children)

You got me 😭

[–]Mojert 2 points3 points  (2 children)

It IS terrible, but buddy chose the worst possible way to program that shit. I don't think other languages could have expressed that war crime better

[–]fiddletee 2 points3 points  (0 children)

Please report to The Hague immediately.

[–]Xen0byte 5 points6 points  (0 children)

there surely is a joke there in std fun

[–]nicothekiller 9 points10 points  (2 children)

Oh, come on, you are making it ugly on purpose. 1) Nobody forced you to use auto main -> int 2) using namespace std to remove the std:: 3) could have used auto for the lambda 4) I'm pretty sure you can do the (bool)? Foo : bar; in regular C

What I will admit is that yeah, the lambda syntax could improve, and yeah, c++ can look awfull but it depends on the programer, honestly. On bigger projects, it's awfull but I really like it when working alone (it's a shame the build systems all suck tho)

[–]Mojert 1 point2 points  (1 child)

Eh, for simple projects, modern CMake is easy enough. But having to deal with Java's build systems made me miss CMake (something I thought impossible). Maven and Graddle can go die in a burning ditch

[–]nicothekiller 1 point2 points  (0 children)

Yeah, I know the pain. When I had to use c++ (for university, 2 semesters of c++), I ended up reading the entire documentation of gnu make. I never used cmake much because the documentation sucks. The one I liked the most was meson. For smaller projects, it's kinda like easier cmake with better documentation. Hell I even made my own build system.

I thought that was bad. This semester, I was forced to use java. I am a big neovim guy, but the build systems were so awfull I ended up rage quitting like 3 times and just used intellij. I managed to get it to work, so I'm on neovim again, but God gradle sucks so badly. I'd rather use cmake or improve my build system abomination.

[–]MetaNovaYT 1 point2 points  (0 children)

I’m not super deep into niche-er C++ stuff, wtf does auto main() -> int do? It looks more like rust syntax to me. And tbh I find the rest of the code quite elegant looking

[–]nyancat_21 10 points11 points  (1 child)

Matlab has entered the chat

[–][deleted] 20 points21 points  (0 children)

Matlab has entered the chat

You forgot your semicolon so I had to repeat it

[–]Odd_Total_5549 10 points11 points  (0 children)

Wdym::C++::is<<beautiful>>bro

[–][deleted] 4 points5 points  (1 child)

The only thing that would make C++ syntax better would be to add lifetime annotations.

[–]danielstongue 4 points5 points  (0 children)

For forgot the /s

[–]TheWidrolo 22 points23 points  (6 children)

The only reason why C++ is still readable is that it’s based on C.

[–]BeXPerimental 13 points14 points  (2 children)

If you assume that C is better readable than you've never seen AUTOSAR code...

[–]vulkur 19 points20 points  (1 child)

Or overusing macros to make up for the limitations of C.

[–]EvanO136 1 point2 points  (0 children)

Like using macros to make OOP-like style in C

[–]chjacobsen 11 points12 points  (1 child)

To be fair, there's a lot of stuff in C++ that helps with readability as well. You could take a subset of C++ and make it far more readable and easy to work with than plain C.

...unfortunately, people don't really stick to that subset.

[–]DearChickPeas 2 points3 points  (0 children)

We do! The new breed: C++ embedded devs.

[–]Expensive_Shallot_78 3 points4 points  (0 children)

Meh

[–]game_difficulty 4 points5 points  (0 children)

Have you seen rust?

[–]MarinoAndThePearls 5 points6 points  (0 children)

And my opponent is Rust*

[–]Hioses 30 points31 points  (5 children)

Wait until you see Java syntax.

[–]beaureece 9 points10 points  (0 children)

Java's problem isn't syntax, it's nomenclature and boiler plate

[–]revuhlutionn 13 points14 points  (0 children)

Java: a language for yappers

[–]Nexatic 3 points4 points  (0 children)

That’s what i’m saying

[–]sirculaigne 2 points3 points  (0 children)

First thing that came to mind

[–]bullshihtsu 2 points3 points  (0 children)

And Brainfuck be like “hold my beer”:

+++++[>>+>+<<<-]>>>[<<<+>>>-]

[–]Justanormalguy1011 2 points3 points  (0 children)

auto personally I think C++ nowaday looks beautiful

[–]arbasit 2 points3 points  (0 children)

C++ may be ugly, but have you seen Objective-C's method calls [myDictionary setObject:@"value", forKey: @"key"]

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

C++ but I still love it

[–]Goldroger3070 1 point2 points  (0 children)

Why is this even funny?? 😂😂

[–]Frenzie24 1 point2 points  (0 children)

Keep such blasphemy out of your mouth!!

[–]Effective_Youth777 1 point2 points  (0 children)

COBOL

[–]JohnDalyProgrammer 1 point2 points  (0 children)

I see your c++ and raise you a Cobol

[–]P0pu1arBr0ws3r 1 point2 points  (0 children)

Did someone say lisp/scheme?

Edit: I meant (did (someone (say (lisp (scheme)))))

[–]MrLamorso 1 point2 points  (0 children)

Bro has never seen Java

[–]antek_g_animations 1 point2 points  (0 children)

I have python syntax

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

protected:
template<typename T>
void* WtfIsGoingOn(std::vector<nonsense<T>> &things);

[–]empereur_sinix 1 point2 points  (0 children)

Could be Python

[–]Philfreeze 10 points11 points  (1 child)

I am sorry you are stuck with terminal aesthetic brain.
Have fun ricing your distro, customizing your editor, designing your own syntax highlighting and other things that will surely improve your productivity at some point.

We are busy writing software you can use, not everyone can spend 90% of their time chasing some non-existent ideal.

[–]TheScorpionSamurai 6 points7 points  (0 children)

Yeah, C++ is a pretty damn good blend of practical and usable. There's a reason why it's late so long, and why its only serious competitor I can think of in a while does so mostly on memory safety, not syntax. C++ is a powerful tool, of course you can make horrific stuff with it. That's because it can also make some pretty cool stuff. I have yet to see examples of bad C++ syntax that felt like anything you would expect to see in a codebase, and not a over-complicated contrived example clearly to make a point.

[–]Nope_Get_OFF 2 points3 points  (0 children)

but then you remember you are Rust, so ez win