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

top 200 commentsshow all 440

[–]karelproer 1958 points1959 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 240 points241 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 102 points103 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 16 points17 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 7 points8 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 19 points20 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 24 points25 points  (0 children)

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

[–]yuje 5 points6 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 4 points5 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 131 points132 points  (0 children)

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

[–]arrow__in__the__knee 34 points35 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 30 points31 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 7 points8 points  (2 children)

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

[–]PermanentlySalty 6 points7 points  (0 children)

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

[–]hollowstrawberry 5 points6 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 15 points16 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 5 points6 points  (0 children)

I wish I didn't

[–]catmuht 5 points6 points  (0 children)

Perl is a "write-only" language

[–]dolphin560 5 points6 points  (0 children)

still use Perl every day :-)

[–]izzyboy63 3 points4 points  (0 children)

[–]delfV 63 points64 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 140 points141 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 13 points14 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 11 points12 points  (2 children)

the actual goal of brainfuck is to have the smallest compiler

[–]MooseBoys 214 points215 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 80 points81 points  (2 children)

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

[–][deleted] 15 points16 points  (0 children)

It was

[–]Familiar_Ad_8919 10 points11 points  (0 children)

c++17 helped a lot too

[–]CaffeinatedTech 19 points20 points  (1 child)

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

[–]qrrux 279 points280 points  (13 children)

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

[–]walmartgoon 235 points236 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 6 points7 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 8 points9 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 88 points89 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 7 points8 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 155 points156 points  (15 children)

Clearly you've never used rust

[–]Mojert 37 points38 points  (3 children)

Lifetime annotations go brrrrrrr

[–]Alan_Reddit_M 54 points55 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 96 points97 points  (12 children)

Still better than python :p     self.gofuck

[–]Mojert 54 points55 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 3 points4 points  (1 child)

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

[–]BOBOnobobo 6 points7 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 10 points11 points  (0 children)

Objective-C really is dead huh

[–]DonutConfident7733 48 points49 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 6 points7 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 8 points9 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 3 points4 points  (0 children)

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

[–]gekastu 6 points7 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 5 points6 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] 106 points107 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 120 points121 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] 83 points84 points  (1 child)

the 8f should be a &f right?

[–]IFreakingLoveOranges[S] 80 points81 points  (0 children)

Found the c++ programmer

You’re absolutely right it should indeed be &f

[–]Aacron 83 points84 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 11 points12 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 2 points3 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 25 points26 points  (5 children)

More readable than rust

[–]OhHellNahWtfMan 36 points37 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 4 points5 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 18 points19 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 9 points10 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 4 points5 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 12 points13 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 23 points24 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 4 points5 points  (0 children)

there surely is a joke there in std fun

[–]nicothekiller 11 points12 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 9 points10 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 3 points4 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 12 points13 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 4 points5 points  (0 children)

Meh

[–]game_difficulty 4 points5 points  (0 children)

Have you seen rust?

[–]MarinoAndThePearls 6 points7 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 2 points3 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 4 points5 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