Looking at C++14
meetingcpp.com
meetingcpp.com
>char c = 0b01011010
I can't believe this took TWENTY YEARS (or at least that's how long I personally have been waiting). Hurray! (I'm going to hobble my walker over to the desktop and start codin' binary.)
#include <boost/utility/binary.hpp>
char c = BOOST_BINARY(01011010); #define HEXIFY(X) 0x##X##LU
#define B8IFY(Y) (((Y&0x0000000FLU)?1:0) + \
((Y&0x000000F0LU)?2:0) + \
((Y&0x00000F00LU)?4:0) + \
((Y&0x0000F000LU)?8:0) + \
((Y&0x000F0000LU)?16:0) + \
((Y&0x00F00000LU)?32:0) + \
((Y&0x0F000000LU)?64:0) + \
((Y&0xF0000000LU)?128:0))
#define B8(Z) ((unsigned char)B8IFY(HEXIFY(Z)))
And now you can write: B(01011010)
Etc.If you like this, see my blog post about bithacks.h:
With that you can simply do char c = 0x5A. It is more readable since there are more distinguishing characters and is shorter. I actually made a mistake when I first scanned your numbers and had to look carefully. Imagine if the number was a 64bit integer.
Also <bitset>, if you intend to use c++ correctly.
char unsigned bottomLeftCorner[8] =
{
0b11000000,
0b11000000,
0b11000000,
0b11000000,
0b11000000,
0b11000000,
0b11111111,
0b11111111
};
They may, at times, also make sense when coding some low-level protocol.https://groups.google.com/a/isocpp.org/forum/?fromgroups#!fo...
But hey, at least they have a Turing-complete template language to go with their macros! Priorities, right?
Any C++ user (you know, the people who actually use the language) will tell you that templates is a central part of the language and something that is far more important than introspection.
Anyway, like I said in the other comment, there's a study group for reflection now. We'll see what comes out of it.
Funny, because I am a heavy C++ user (why did you assume differently?). C++ probably accounts for between 1/3 and 1/2 of my lifetime lines-of-code. Trouble is, I've had to use it for more than algorithms work, which is the only place I've ever seen templates shine. I've used a half dozen C and C++ GUI frameworks that painstakingly work around the introspection issue, and while these frameworks often make do quite nicely without templates, they always have a bolted-on monstrosity of an introspection system. Qt is probably the most direct example: they built their own preprocessor/parser around C++ to take care of their need for introspection.
I'm glad there is a study group, but the absence of introspection has been hurting the C++ community for a long time. It's the flaw that has launched 1,000 high-level languages and 100,000 dirty hacks.
And with that you can build reflection:
(Poe's law applies, sorry if you were attempting humor and I missed it.)
GCC C++11 status: http://gcc.gnu.org/projects/cxx0x.html
Clang: http://clang.llvm.org/cxx_status.html
MSVC is not as good. I don't have any links handy, but anecdotally it still fails to compile some of my code that compiles fine in GCC.
Here's the library features table: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#s...
Not feature complete if you take that into account, I'm afraid.
A little out dated but a good starting point. I'm using gcc 4.6.1 and am loving the C++11 features, only thing I've noticed it missing is implicit capture of this in lambdas.
Rust may be a different story (still too soon to tell) because it shares many of the fundamental philosophies of modern C++ without having a "bolted-on" feel. Still, it will be very hard to ever displace C++, because so much code is currently written in C++ and C++ has proven to be a very good language for code that needs to last decades.
This is one of my big frustrations with Go. I see lots of ugly `interface` based patterns.
I wish more languages would adopt Haskell's typing system (at least partially). It is truly beautiful.
I'm pretty sure that Rust devs are aware of that which is why they made Rust compatible with C/C++.
For a small example, a friend talked me into implementing a few Scala collection operations in C++11. Here's the result: https://gist.github.com/LnxPrgr3/6547131
Usage looks like this:
const collection<vector<string>> names = {"Daniel", "Chris", "Joseph"};
return names.reduce_left<string>([](const string &total, const string &value) {
return total + ", " + value;
}) == "Daniel, Chris, Joseph";
// ...
const collection<vector<string>> strs = {"1", "2", "3", "4", "5"};
auto rv = strs.map<collection<vector<int>>>([](const string &x) {
return atoi(x.c_str());
});
return rv.size() == 5 && rv[0] == 1 && rv[1] == 2 && rv[2] == 3 && rv[3] == 4 && rv[4] == 5;
This is from a collection of tests, which looks like this: struct test {
const char *name;
function<bool ()> fn;
};
const vector<test> tests = {
{"Foldleft", []{ /* .... */}},
{"reduceLeft on empty throws", []{ /* ... */ }},
// ...
};
for(auto &test: tests) {
cout << test.name << ": " << flush << (test.fn() ? "PASS" : "FAIL") << endl;
}
I would've never considered something like this useful in C++03—callers would have to create named functor classes just to do some trivial one-line operation, this vector of tests would've had to have been a series of push_back calls, and iterating over it would've been quite a bit uglier.This isn't at all an exhaustive list, but these are the biggest things that come to mind when I think of what C++11 gains over C++03.
In benchmarks Go keeps performing somewhere between Java and C++, but it isn't at the baremetal performance of C / C++ yet. Don't know if it can get there with its abstractions. Rust is closer, but it concedes a lot of glyphic syntax (such as requiring :: for scope like in C++ rather than, say, one colon) but I don't see it hitting prime time until Mozilla is ready for Servo to enter Firefox. It needs a big project behind it to show its capable.
There is a wide range of algorithms to find/modify/replace data in containers.
Let's say you have a set of ints, doing what you want is the following:
std::set<int> blah;
// ... some stuff happens ...
if (blah.find(123) != blah.end())
{
// ...
}
Now, you're saying, "but my container doesn't have find!". Not a problem, you can use std::find! std::vector<int> v;
// ... some stuff happens ...
if (std::find(v.begin(), v.end(), 123) != v.end())
{
// ...
}
Note that v can be ANYTHING, as long it supports forward iterators (which all containers do).Now you're saying, "but it's not very efficient! The complexity of find is O(n)!"
True, true. If your container is sorted, you should use binary search O(log n):
if (std::binary_search(v.begin(), v.end(), 123))
{
// ...
}
What's great about this is that it works on any container, provided it's sorted.Then, what you can do is write a metafunction that will call the member function find() when it exists or use std::find() when there's none. This will automatically, and at compile time, use the most efficient way to check for the existence of an entry.
Compare this syntax:
> if (std::find(v.begin(), v.end(), 123) != v.end())
To
> if (123 in v)
If in is an operator and overloaded by std::vector, then it's easy to implement.
However, searching a `std::vector` is not really part of its implementation. So, requiring every single range to overload an operator for trivial searching is not good, especially since there are only a few containers that have non-trivial searching.
Instead, the range-based find could be specialized for containers that have non-trivial searching instead(perhaps it calls a `.find` method if available otherwise it does trivial searching).
In [Linq](http://pfultz2.github.io/Linq/), the find is specialized for mapped containers and for strings(it doesn't check for a `.find` method since that can't be done on msvc). So you can search a `std::vector` like this:
std::vector<int> v = { ... };
auto it = v | linq::find(123);
And you can also search the keys of a map like this: std::map<int, std::string> m = { ... };
auto it = m | linq::find(123);
Plus, it has a contains function, so you can do this: if (v | linq::contains(123))
Or this: if (m | linq::contains(123))
There really is no need for a new operator just for this, since a function will suffice. However, if you really inclined to this, you could always write your own [named operator](https://github.com/klmr/named-operator)(although I don't know if it would become standard): if (123 <in> v)lol, no, god no. I think you got the STL completely wrong.
The fact that algorithms are separated from containers is a major feature of the STL and one of the major reasons why it is so awesome.
By having algorithms separated from containers you implement algorithms only once and only have to give your container the right properties to use (an) algorithm(s).
You reduce coupling and the chances for errors and bugs. When you need to switch to a different containers, you don't have to rewrite your code. You can also try different algorithms easily.
> if (123 in v)
I'm sorry but C++ is about describing precisely what you want to do and how you want it to be done to get the maximum performance out of your machine.
What is "in"? What does it do? How does it allocate memory? How can I get the position of the entry? Which algorithm is used to search for the entry? What must I do to support "in"?
On the other side,
> if (std::find(v.begin(), v.end(), 123) != v.end())
I use a O(n) algorithm to search from the beginning to the end of the container for an entry equal to 123.
Hold on a minute. Why is this even a thing? Do people really use HUGE numeric literals and have so much trouble reading them that this is needed?
This just sounds like another parsing nightmare that really should belong in syntax highlighting rather than exist as some obscure language feature.
Yes. Engineering code uses numeric literals with many digits all the time.
> and have so much trouble reading them that this is needed?
Digit separators make digit omissions/additions much easier to spot. Imagine spending a day trying to track down a "everything explodes" bug, systematically eliminating numerical sources of error one by one, only to find that the problem is a misspecified boundary condition that you didn't catch the first time around because you were counting the number of zeros as opposed to the number of digits.
c = 3000'000'000 /* m/s */
^ I can spot this out of the corner of my eye. c = 3000000000 /* m/s */
^ This? Not so much. c_millisecs = 50000 * 60 * 1000; // 50,000 minutes(1000 * 60 * 60 * 24 * 2) == 2 days
Stop using this bastard of a language. Its an offront to software engineering and must simply die
Assuming Rust 1.0 is released sometime this year, it'll still take a number of years before Rust even begins to offer the very wide range of libraries/frameworks that are available to C++ developers.
Interfacing with these existing C++ libraries/frameworks may speed things up, but at that point its disputable whether it's really Rust being used.
Rust may be among the most promising alternatives, but it's just not there yet, and won't be for some time.
I make games. What am I supposed to code that in? Fucking javascript? Ruby? C#? Go stfu and die yourself. If you want to come up with a language that can get the job fucking done than by all means, go for it and fail miserably. Otherwise, stop using any of the products that leverage C++. We don't want you.
I find it amusing that the new languages being heavily touted in the non-functional space (that would be Go, D and Rust) are all using C and C++ as their targets for replacement. Everybody loves to hate C and C++, yet the tech world literally runs on them, and will for the foreseeable future.
This isn't to say there isn't anything better, or that they'll never be replaced.
You also misspelled "affront."