C++, The Good Parts

What do you see as the most important, relevant features of today's C++? What are the most important topics to learn?

A little background to put this question in context: I've been studying C++ for a couple of years now, and of one thing I am certain: C++ is vast, with a 40+ year history. There's a lot of information out there, and a large chunk if it is either dated, obsolete, downright wrong, or all of the above. I struggle more with understanding _what_ to learn than the actual subject matter.

Example: In an effort to remedy this issue, I took a couple professional development courses in C++. We spent a great deal of time on learning raw pointers in different shapes and sizes: pointers to arrays, arrays of pointers, polymorphism and double-dereferencing, etc... but not a word about smart pointers. I went into an interview thinking that I was ready to handle any question about pointers. First question:
INTERVIEWER: "Explain the different types of smart pointers, and why we need them."
ME: "Uhh... I haven't really worked with smart pointers."
INTERVIEWER: "Thanks for your time; please be sure to surrender your temporary badge on the way out."

So, I'm looking for what's relevant in today's C++ world. Through trial, error, pain, mistakes, and "going over the fence the hard way," here are a few important and relevant topics today:

1. Smart pointers
2. the Standard Library, especially containers (Vector, Map, etc)
3. Big-O notation, and how to calculate it.

Can you add to this list?

THANK YOU. Sincerely, Keith :^)
You've hit upon a bugbear of mine - the # of posts that appear on this forum from those who've started learning C++ with problem after problem on C-style arrays instead of std::vector etc, raw pointers instead of smart ones, char* instead of std::string ... I could go on and on but nothing about the standard library and more recent features and these are not at all difficult, honestly. The following link should bring you up-to-date until C++11:

http://blog.smartbear.com/c-plus-plus/the-biggest-changes-in-c11-and-why-you-should-care/

And for C++14: http://www.drdobbs.com/cpp/the-c14-standard-what-you-need-to-know/240169034?pgno=1

And finally C++17: http://stackoverflow.com/questions/38060436/what-are-the-new-features-in-c17

Purchasing (computer) education is just like any other purchase really, buyer beware, do your research and make sure you enroll at a program that's teaching relevant stuff or at least keep a look out for latest industry standards

Last edited on
I'd add use RAII techniques. Ie. prefer using constructors over calling "setter" functions, prefer to let the destructor free resources instead of manually freeing resources by calling "closer" functions. Initialize variables at definition,
http://en.cppreference.com/w/cpp/language/raii

Use constructor initialization lists, utilize move/Rvalue reference semantics , proper use of list initialization.

http://www.stroustrup.com/C++11FAQ.html#init-list
http://www.stroustrup.com/C++11FAQ.html#rval
http://www.stroustrup.com/C++11FAQ.html#uniform-init

Ranged based loops: http://www.stroustrup.com/C++11FAQ.html#for

Proper use of exceptions.

Maintaining const correctness.

See: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md for more ideas.


+ Multithreading
C++ has an expressive type system - it's quite incredible what can be achieved with templates and Template Meta Programming (TMP). Not that I have a lot of experience with it, but have seen plenty of really clever template code.

At it's most simplest :

1
2
3
4
5
6
7
8
9
10
template<int N>
struct MyIntType{
  int number =N;
};

// these 2 are different types:

MyIntType<1> Fred;
MyIntType<2> Ginger;


The boost library has a more formal version of this: int_ in the MPL library:
http://www.boost.org/doc/libs/1_63_0/libs/mpl/doc/refmanual/int.html
http://www.boost.org/doc/libs/1_63_0/?view=category_Metaprogramming


This is very simple concept is surprisingly useful, consider a circular arc class. We have these Points: Centre, Begin, End, PtOnArc, Middle. And we have these doubles: Radius, BeginAngle, EndAngle, ArcLength and numbers to do with bisection of the chords. Bisection is necessary when the Arc is constructed from 3 points on the arc. We need for all these to be of different types so we can overload the constructors. We can create structs/ classes using the above concept to do this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<int N, typename T = double>
struct DoubleType{
  T value;
};

// the suffix _t means type
using Radius_t = DoubleType<1> ;
using BeginAngle_t = DoubleType<2> ;
using EndAngle_t = DoubleType<3> ;
using XOrdinate_t = DoubleType<4> ;
using YOrdinate_t = DoubleType<5> ;

struct Point {
   XOrdinate_t X;
   YOrdinate_t Y;
};


Now these can be used to create an Arc class with all it's different constructors and functions. The above example is bare bones, for example more should be done to only allow floating point types.

This example is the merest scratch in terms of what can be done, there are lots of examples out there that are very clever and complex.
C++ has an expressive type system


Lately I have been thinking that when we use auto (and I do it regularly too) perhaps it defeats the purpose of this type system. typedef/using etc to avoid some additional typing I can understand but (too much) auto? Is that a good thing? Yes, we can always back out the type with typeid etc but still ...
gunnerfunner wrote:
Lately I have been thinking that when we use auto (and I do it regularly too) perhaps it defeats the purpose of this type system.


Hi :+)

I think the use of auto is a different question: The expressiveness basically comes from the use of templates to make new types; the use of auto and using can also help fix difficult to diagnose compilation errors as well as save some typing.

However, I don't particularly like this:

auto a{1.2};

I think it's clearer for humans to do this equivalently:

double a{1.2};

Maybe that is too simplistic: there might be other examples which are different.

Just had an idea about auto a{1.2}; : maybe in the future if one could specify some extended precision type to be the default for all the floating point types instead of double, then that use of auto would be an easy way of using that precision type.

Have you some examples of "too much auto" ? How do you think it defeats the type system?

I am by a very long way far from being an expert, but I have a suspicion that the benefits of auto etcetera might outweigh any disadvantages.

Regards :+)
closed account (48T7M4Gy)
http://en.cppreference.com/w/cpp/language/auto


auto is automatically typed so in reality nothing is defeated. I guess that's why it was introduced. This change for the better is a good example of easing the scope for errors without compromising strong typing.

Iterators for any of the containers with or without templates being involved are a great case for auto as we all know.

Within reason, let the machine do all the work.

Here's one case for it:
https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/

Sutter's suggestion is that it allows us to more easily "write code to interfaces" -- in a word, that it helps enable duck typing.
That's certainly true but it's another question entirely if duck-typing is always good.
Last edited on
tIM, kemort, Max - many thanks for the posts and links. You folks have convinced me now that auto is the way to go. Thanks again.
closed account (48T7M4Gy)
At the risk of preaching to the now-converted :)
However, I don't particularly like this:
auto a{1.2};


I've never taken much notice of it before but come to think of it, what else could it be other than a double ( ignoring float ). Anywhere else that variable a appears in scope it will be type-checked the same as everything else is. And if you need to go back to check what a variable is in the development stage, there it is.

Of course the personal preference/style thing is still there so everybody wins.
what else could it be other than a double


That's right, but for mere humans, double a{1.2}; is more obvious.Trivial and pedantic, I know, but there you go :+)

Cheers!
Ah, one can do this:

auto a = double{1.2};

GOTW94 wrote:
Guideline: Consider declaring local variables auto x = type{ expr }; when you do want to explicitly commit to a type. It is self-documenting to show that the code is explicitly requesting a conversion, it guarantees the variable will be initialized, and it won’t allow an accidental implicit narrowing conversion. Only when you do want explicit narrowing, use ( ) instead of { }.
Last edited on
closed account (48T7M4Gy)
but for mere humans

In the interests of avoiding the wrong end of the stick being taken the subject of my comment is mere compilers. Humans are irrelevant once a C++ compiler, which generally spits out venom when encountering ambiguity, takes over.

float vs double could be a case where the explicit declaration of float is important.

The beauty of the compiler is that it can handle double a = 1.2; as it has for decades for vast numbers of people who feel more comfortable with that and don't, can't or won't change.

life is good :)
Topic archived. No new replies allowed.