7 ms·
Wow, looking at the code in the example, this looks almost nothing like the C++ I used to write 15 years ago. The language really has evolved massively and it s
by terryf 5y ago
Wow, looking at the code in the example, this looks almost nothing like the C++ I used to write 15 years ago. The language really has evolved massively and it seems in a good direction.
- vaylian 5y agoAgreed. Can someone explain the following? std::string product{"not worked"}; Searching for "curly braces C++ string" is not really productive. I'm also curious what [&](job& my_job) { } means.
- ktpsns 5y agoThe first one is a curly braces initializer. The second one is a lambda function / closure over my_job.
- dataflow 5y agoIt's called uniform initialization syntax (aka "brace initialization" aka list-initialization [1]). tl;dr is everyone loves it due to the terseness, but I recommend against it. It's kind of like a forced cast/coercion in some ways (and it also looks ugly). Also be careful with parentheses since C++20; if they invoke implicit (aggregate?) constructors that would've traditionally needed {}, I think you can also run into similar casting issues. I just ran into this one a couple days ago; I haven't narrowed it down yet, but it seemed to be due to this. The second one is a lambda (which, if you're not familiar with the term, are anonymous functions/functors); the entries in the initial brackets define the captured variables (if any), and whether they're captured by reference (with ampersand) or by value (without). [1] https://en.cppreference.com/w/cpp/language/list_initialization https://en.cppreference.com/w/cpp/language/list_initializati...
- gpderetta 5y agoIt is in fact not a forced cast, unlike T() initialization that can indeed be a cast. Uniform initialization is great, except for the unfortunate interaction with initialized_lists (yes, we can't have nice things), but if you do not have an initializer_list constructor in your class you do not have to worry.
- dataflow 5y ago> It is in fact not a forced cast Why do you say this when you can explicitly see I specifically made sure to avoid claiming it is in fact a forced cast, and instead I said it is kind of like a forced cast? Clearly I meant something other than that it was actually a forced cast, right? > if you do not have an initializer_list constructor in your class you do not have to worry. Which is precisely an example of my point about it being problematic. How would you go about this when you don't know everything about a class? Like, say, in a template? And how do you prevent your code from silently breaking if a class you use later adds an initializer_list constructor? > Uniform initialization is great I disagree. It's awful. It's just a minor cosmetic change (which we can call an "improvement" for the sake of argument, though I think that's also dubious and the syntax is just ugly) that introduces pitfalls in the actual semantics of your program. That's not a great trade-off; it's a terrible one.
- qalmakka 5y ago> a minor cosmetic change (which we can call an "improvement" for the sake of argument, though I think that's also dubious and the syntax is just ugly) that introduces pitfalls in the actual semantics of your program std::int64_t i64 { 44 * 44 * 44 }; std::int8_t i8 = i64; // perfectly fine std::int8_t i8_2 { i64 }; // refuses to narrow the int uniform initialization resolves lots of headaches, like T() being ambiguous at times with functions, narrowing, etc.
- dataflow 5y agoI don't see failure on i64 -> i8 as beneficial here; it's harmful if anything. Integer conversions already happen in all sorts of constructs. Which is why compilers have warnings for them. If you don't like them, you can enable warnings (or even set them to errors if you want to outright prohibit them). If you think they should happen implicitly then there's nothing particularly interesting about construction sites vs. assignments or really anything else; there's no reason integer conversions should be treated specially for construction sites. If anything, that would make you feel safer than is actually warranted. With T() being ambiguous, you can already syntactically disambiguate. With extra parentheses or whatever other construct the case may warrant. As people have been doing all these years. Again, it's just a minor syntactic inconvenience.
- going_ham 5y ago>std::string product{"not worked"}; This is string initialization. Now product = "not worked". >[&](job& my_job) { } A lambda function that takes in a reference to job! C++ has definitely evolved but the package management is still difficult unlike cargo!
- Fronzie 5y agoWith Conan, vcpkg (https://devblogs.microsoft.com/cppblog/all-vcpkg-enterprise-features-now-generally-available-versioning-binary-caching-manifests-and-registries/ https://devblogs.microsoft.com/cppblog/all-vcpkg-enterprise-...) things are getting better. For personal projects, vcpkg with manifests is a breeze to use.
- pjmlp 5y agoI second that, now if only the C++/WinRT team would get back the GUI tooling it took away from us by killing C++/CX.
- sudoankit 5y agostring product{"not worked"} is initializing the string product to "not worked". It's the same as std::string product; product = "not worked"; [&](job& my_job) { } is a lambda expression. & is capturing the variable by reference. my_job is the parameter being passed which is a pointer of type job. Please check https://en.cppreference.com/w/cpp/language/lambda https://en.cppreference.com/w/cpp/language/lambda and https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=msvc-160 https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-... for more.
- kleiba 5y ago> It's the same as std::string product; product = "not worked"; Not a C++ person, so please forgive my ignorance, but what is the difference between the above and sth. like: std::string product = "not worked"; or std::string product("not worked"); (Are these even legal C++ statements and, if not, why not? ;-))
- MakersF 5y agoIn practical terms, none. They are the same, and the same as using the curly braces. From the POV of the standard, those are different kinds of initializations. C++ has like 12 different ways of initializing variables, and the differences are quite confusing, but in practical terms in my experience I never had to care too much beside making sure native types are initialized to some specified value. You can probably find some talks on YouTube talking about the initializations of c++, and 1h30m is probably not enought to cover all the details :')
- kleiba 5y agoYeah, that sounds like C++, I suppose. Thanks very much.
- klibertp 5y agoBoth are valid, and were the only ways of initializing objects before C++11, I think. Brace initialization has an advantage in that it allows you to initialize compound values, like containers and structs, even if they're nested: std::map<int, std::string> m = { // nested list-initialization {1, "a"}, {2, {'a', 'b', 'c'} }, {3, s1} }; Ref: https://en.cppreference.com/w/cpp/language/list_initialization https://en.cppreference.com/w/cpp/language/list_initializati... https://en.cppreference.com/w/cpp/language/aggregate_initialization https://en.cppreference.com/w/cpp/language/aggregate_initial...
- 72deluxe 5y agoCurly braces is an "initializer list". Stroustrup covers it in the blue C++ book he wrote about C++11.
- nspattak 5y agoWhat you need to search for is "list initialization" (eg https://en.cppreference.com/w/cpp/language/list_initialization https://en.cppreference.com/w/cpp/language/list_initializati...) . I understand that it is not the obvious thing to do. If you search for c++11, it was one of the features that were introduced then. lambda expressions were also introduced in c++11 but are also found in other languages so they are easier to understand for non c++ people.
- ncmncm 5y agoYes, C++ has got quite a lot more fun to use. C++20 is almost as different from C++11 as C++11 was from C++98. If you make a point to always use the newest features, where there is a choice, and really put the type system to work for you, programs generally run right the first time, once the compiler is satisfied. In the past ten years I have spent more time filing compiler bug reports than debugging C++ memory usage errors. It is amazing how many people are all up-to-date on what is new. I think people who complain about C++ on HN must be complaining about a much older version of the language.
- pjmlp 5y agoSpeaking from my experience, thers is the C++ I use on hobby projects and see at talks like C++Now, and there is the C++ I get to see in the wild when plugging native libs into our Java/.NET code bases. Even Android NDK and some subsystems are good examples of this second C++ flavour.