C guy here. I'm assuming you're serious and not being sarcastic... which is a nontrivial assumption, because that line you posted looks like something out of the foul depths of hell.
You aren't going to run out of lines any time soon. Who cares whether your data structure definition is 1 line or 5?
> because that line you posted looks like something out of the foul depths of hell.
I must say I laughed-out-loud at that, mainly because I've been on both side of the divide when it comes to opinions on verbose std definitions. It is an odd feeling to simultaneously feel revulsion and nostalgia towards a line of code.
I do think there is a non-trivial, and sometimes massive boon gained from concise definitions. It's the difference between an acronym in natural language vs referencing a concept by its full verbose name. The shorter the definition of a concept, the fewer units used by your working memory when referencing that concept, thus freeing your mind to higher level considerations.
I agree - I've found the STL a massive productivity boost, for all its ugliness. It's worth it for std::vector and std::string alone, and I also like std::map (even though the API teeters on the boundary between genius and insanity) and std::set. All there for your use, with your own data types, out of the box.
I discovered the STL one day in February 1999, by accident, when looking for something else in the VC++ help. Once I realised what I'd found, I gave up C entirely within about 1 week.
Foul depths of hell? I've never programmed in C or C++, but this seems to me to be a map from strings to vectors of strings. Reads easily. I don't like the :: namespace separator, but what can you do...
I used to do this. But then I realized I would be importing all symbols from std into my code. Including ones that might get defined in the future (similar to python's 'from foo import *'), which might conflict with some of my own symbols.
Hence, I now implicitly import each symbol I need with something like 'using std::map;' (similar to python's 'from foo import bar, bar2').
I've found that the 'using' statement can be used even inside a function to restrict the importation to just a single function.
Interesting; I never thought of that analogy to Python. I've just had it drilled into my head from everything I've ever read about C++ that "using namespace std" is terrible, and I shouldn't use it.
Except the analogy to Python lacks one critical point: C++ headers and Python imports do not work in nearly the same way. Do not EVER use a "using namespace <foo>" in a header file; any code that #include's such a header will pull this in.
In .cpp files it's ok (and almost required if you're using boost, unless you want boost::foo:bar::type everywhere). It still requires a bit of thought, though.
And can't be _implemented_ in any language. C gives you at least the charming fact that you can implement one without any overhead of objects, classes, implicit memory management or some other concept, just having a lightweight implementation that you may use in an environment without any libraries, like std or else..
So what you're saying is that C lets you write it on your own. In fact, and this might sound crazy, but you can do that exact same thing in C++, it's just that people don't because the C++ standard library provides plenty of performant and featureful data structures for you.
Besides, anything the C++ standard template library map does when implementing a red-black tree is exactly what you would need to do if you wrote your own, minus having things like allocators (which are incredibly useful for those that need them). You speak of overhead due to "objects, classes and implicit memory management". Inevitably, any implementation of a data structure of substance in C ends up looking like c++-ified C. Want to create your hashtable? Call hashtable_init and get back a hashtable_t. Want to insert into it? Pass your hashtable_t, a key and a value into hashtable_insert. Even worse, you either have the choice of making all of your data void* in the data structure and casting into and out of your interface or making awful macros to define the various methods and structures for the types you would like to use. It's like you're stubbornly writing C++ in C.
I'm not sure why I'm getting sucked into this again :-) but it doesn't have standard, portable libraries. It also doesn't have the right abstractions in the language to provide clean and safe (i.e. no void* and no brittle preprocessor magic) implementations of such.
I've written C for most of my life, you can do great things with it. I also have a love/hate relationship with C++ and Python. There is no perfect language, they all have to make tradeoffs.
yes, even standard libs, but they arent that promoted as c++ std libs, as most of them are just apis for system interaction, only a minority are useful out of the box algorithms.
no its not c++ish, its simply an implementation which is technically similiar to c++, because they are at some core syntax/semantic similar. i didnt said that its the new wheel, or better or worse. its just free of third party stuff, which will be compilable anywhere only dependent of the compiler used. and i didnt exclude that this is exlusive for C, sure this applys to c++ as well. but not if you want to use feature complete c++.
Well, what I posted wouldn't be in a tidy codebase. You'd have something like:
// foo.h
typedef std::map<std::string, std::vector<std::string>> StringToVectorString;
// foo.cpp
// in several places you can just use:
StringToVectorString foo;
well the thing is, it also works for std::vector<string>, or std::vector<int>, or anything you want. Last time I checked in C you'd have to either duplicate all your array code for each type or resort to something like void*. Only for that I'd use C++ (yes, you can use it without classes if you want).
Last time I checked in C, all pointer types where the same storage size. There's no need to define the same data structure multiple times by using templates. You just use casts.
... which is fine for creating data structures containing pointers to things created elsewhere, but it doesn't work if you want your data structures to contain more complex data types, without the overhead of another layer of pointer redirections.
Nope. There is no need in C for all pointers to be the same size. An implementation is free (and there indeed, exist some) where a char* is a different size from an int. You can* safely cast any data pointer to void, and a void back to any data pointer. POSIX requires that function pointers can do this; the C standard doesn't require it.
Now, that said, it is possible to write generic link list routines (I've done it) but the devil is in the details.
You aren't going to run out of lines any time soon. Who cares whether your data structure definition is 1 line or 5?