7 ms·
How the STL Uses Explicit
- jimbob45 2y agoWas there ever a reason given as to why “explicit” was chosen over a hypothetical “implicit”?
- RcouF1uZ4gsC 2y agoIn C++ because of how it developed the defaults are not optimal. For example, constructors and conversions are implicit and you have to make them explicit. Variables are default mutable and you have to make them const. Local primitive variables are default unitialized by default.
- JTyQZSnP3cQGa8B 2y ago> Variables are default mutable and you have to make them const Except for the captured variables in a lambda which are const unless you use the mutable keyword. Not a bad idea though.
- Maxatar 2y agoAnd that's only true if you capture by value. If you capture by reference they remain mutable.
- chombier 2y agoI think this is because `mutable` qualifies the call operator of the lambda (like a reverse const qualifier) so by-value captures are effectively const during the call unless the lambda is marked `mutable`. References themselves are always const, but the referenced object may be modified through the reference depending on its constness even though the lambda is not `mutable`. Is there a way to force capture by const-reference by the way?
- gpderetta 2y agoint main() { int x = 0; [&x] { x= 1;}(); // works [&x=std::as_const(x)] { x= 1;}(); // error: assignment of read-only reference 'x' } Not very pretty, but it works.
- cjensen 2y agoI don't know, but a hypothetical 'implicit' would mean converting all unmarked constructors into explicit constructors... which would have broken a lot of existing code.
- pjmlp 2y agoMany of the original C++ decisions come back to how it was supposed to be Typescript for C, which was a reason why it became widely used, and why some warts are the way they are. Like having C structs magically turn into C++ ones, thus implicit rules like these. Anyone that cares about C++ evolution should read "Design and Evolution of C++", not only for how it came to be, also for safety approaches over plain C, that Bjarne is stil arguing for to this day on WG21 meetings.
- senkora 2y agoI don't understand. When does a C89 struct display implicit conversion behavior that would justify making C++ class constructors implicit by-default? For example, the following code does not compile with either -std=c89 or -std=c++98, but does compile if we uncomment the constructor line: struct Foo { int x; /*public: Foo(int x) : x(x) {}*/ }; int main() { struct Foo foo = 5; return 0; } $ gcc -std=c89 tmp.c tmp.c: In function ‘main’: tmp.c:8:20: error: invalid initializer 8 | struct Foo foo = 5; | ^ $ g++ -std=c++98 tmp.c tmp.c: In function ‘int main()’: tmp.c:8:20: error: conversion from ‘int’ to non-scalar type ‘Foo’ requested 8 | struct Foo foo = 5; Maybe I'm missing something?
- pjmlp 2y agoYou are missing that such struct initialization did not exist when C with Classes came to be. Additionally, you are missing the whole package of struct semantics in C++, that while they should at naked eye still look like C structs, they have to also support C++ struct semantics, of memory construction, copy assignment and bitwise comparisaion. Hence why structs and classes are the same, with the difference that structs are public by default, with code generated for keeping the bitwise C semantics, until any of those operations are redifined, at which point the compiler leaves out the job to the developer.
- senkora 2y agoThank you for the response. I still don’t understand why it would be necessary for C++ to default to non-explicit constructors when C at the time did not have constructors and did not have constructor-like struct initialization that mimicked non-explicit constructors. It seems like an unforced error in the language design, rather than a concession to backwards-compatibility.
- lenkite 2y agoI guess if Stroustrup had made "explicit" constructors the default, the C-graybeards would never have adopted C++. Far too much work in porting.
- geerlingguy 2y ago[flagged]
- seanhunter 2y agoEven if you think STL means St Louis, you can't make that sentence confusing becasue none of those other potential uses work in this place. eg "The St Louis" is only a possible construction if you put another noun after it like "How the STL cardinals handle the pressure of big games" (I don't know, I don't really do sports but you get the idea that's a valid sentence). You can't have a sentence "How the STL uses explicit" be at all confusing with any of the examples you gave.
- saghm 2y agoAt least grammatically "the St. Louis" could make sense if you read it as referring to the namesake of the city. "Who was that guy using explicit contstructors, King Louis XIV?" "No, it was the _Saint_ Louis!" I assume that no one named Louis has been canonized since C++ was invented though, and even if it was, using "the" might not be enough to disambiguate in some contexts.
- seanhunter 2y ago...but do we know how the Saint Louis uses explicit? Catholic would-be C++ experts are dying to know.
- saghm 2y agoThere's probably no way of knowing, unfortunately; when the meek inherit the earth, they don't have access to the constructors of the parent class.
- tialaramex 2y agoI feel like you're obliged to omit "Louis" here? Certainly I would feel I can't add this superfluous word, whereas in some cases such words are optional I don't think one is here. I can say "No, it was the Saint" and "No, it was Saint Louis" but I don't think I'd utter "No, it was the Saint Louis" except as a speech error, maybe prompted by rushing like a Colemanball (commonly sports commentators mix metaphors or change their minds about intent midway through an utterance as of course they're live and events are unfolding as they speak, e.g. "That was a decisive mistake although nothing is decided yet").
- metadat 2y agoHow can the C++ statement below even compile? Since "1" and "2" are strings (not even chars). std::vector<int> v = {"1", "2"} // UB Rather than undefined behavior I'd expect a type violation error. But my C++ has gotten a bit rusty.
- ramon156 2y agoId argue that c++ is not type safe. Yes, strings could be converted to ints in theory, but these types are obviously not the same, why not make it more explicit?
- maleldil 2y agoType safety isn't binary but a spectrum. It's obvious that C++ is more type-safe than JS but less than Rust, which is less than Haskell.
- eru 2y agoWell, at some points it becomes even more complicated than just a spectrum. Your types in different languages just track different things. Eg Haskell's types (normally) don't track lifetimes nor ownership, but Rust does that. In contrast, Haskell likes to track whether side-effects like IO can occur at all, while Rust is happy to just let you eg open a file almost anywhere.
- chuckadams 2y agoHaskell has linear types now, so there's your lifetime and ownership, though thankfully they're optional... wrangling linear types makes Rust look friendly and lenient.
- eru 2y agoNice! I've only used linear types in Clean ages ago, but haven't checked them out in Haskell, yet.
- 2y ago
- deleted 2y ago[deleted]