The C++ Programming Language, 4th Edition

Author: Bjarne Stroustrup
All Stack Overflow 10
This Year Stack Overflow 2
This Month Stack Overflow 1


by dmaugis   2019-07-21

Read The C++ Programming Language

Get a Raspberry Pi 2 Model B Starter Kit (Raspberry Pi 2 Model B UK Version, 8GB microSDHC Class 10, 2000mA MAREL power plug, black OneNineDesign case)

Install linux on it (you will have gcc C++ compiler and plenty of stuff) and that s your own computer.

by thgdev   2019-07-21

Well, just for reference, I think The C++ Programming Language by C++'s author is a really good way to start. If you want to practice your problem solving skill alongside with your C++ skill, CodeSignal may help you.

Actually, it is better if you work on some projects, you will learn a lot.

by anonymous   2019-07-21

In your tree constructor, you need to initialize the root pointer to NULL. It's not guaranteed to be initialized as NULL.

When you compile in linux, you can use gdb to show where the source of the segfault is coming from.

Some other notes:

  1. You should assign the value back to root after you've allocated the new node. You're not doing that because you're missing one of the fundamentals of c++. That is, it's based on c. And the thing about c is that is strictly a "by-value" function/method calling paradigm. So all parameters in a function call are by value. When you pass in the memory address for root, you're actually copying the value of the pointer. Then, you're only updating the local value. You need to assign it back to root. If you'd like to learn that concept front to back, I highly recommend watching Jerry Cain's Programming Paradigms course at Stanford.
  2. In your main function, you should try to keep the symbol names as lower_case instead of CamelCase. This helps differentiate variables from types (types should stay CamelCase).
  3. In your TreeType::insert method, you should call the variable tree_node instead of tree. Doing so helps reflect the correct type and avoids confusion.
  4. Whenever possible, try you use the this->root and this->insert notation. Not only will it correctly resolve if you accidentally create a locally scoped root variable, but it's also clearer to the reader where the data or method is defined. Great coding is about communication. It may only take 100-500ms less for the reader to understand where the symbol points to; however, the tiny savings that you can accumulate in avoiding ambiguities add up into a much clearer piece of software. Your future self (and your colleagues) will thank you. See

Lastly, I can overstate enough how important learning from the source is. If you're learning c or c++ for the first time, read and It will save you hours, upon hours, upon hours. After having learned from the source, programming is also A LOT more enjoyable because you understand a good portion of the concepts. And, the truth is, things are more fun when you have a decent level of competence in them.

by anonymous   2019-01-13

The 4th edition of the best C++ book has been just published: The C++ Programming Language, 4th Edition. It contains all the new techniques as well as the new C++11 standard.

by anonymous   2018-03-19

To start with Bjarne Stroustrup in his 4th edition of his seminal book "The C++ Programming Language" doesn't refer to the use of auto as rendered in your code example. But rather to the standard use of the auto specifier as:

  • Specifier for variables where their type is going to be deduced by its initializer (e.g., auto i = 0;).
  • Specifier for function's return type where it's going to be deduced by its trailing return type or from its return statement.

    auto foo(int a, int b) {return a + b; }

In your example you're referring to the use of auto as a placeholder as suggested by C++ extensions for Concepts (N4674) proposal. Unfortunately, this is not standard C++ yet. It was to be accepted in C++17 but it didn't make it. Hopes now rise for C++20. However, use of auto like that is provided by GCC as an extension. Work on C++ concepts for GCC started very early, it even predates the advent of C++11. At some point work on concepts was abandoned and then restarted under another name namely Concepts Lite. Support back then was pretty unstable (e.g., GCC version 5.4). Thus, what you're experiencing is a GCC bug. In more recent versions of GCC this bug has been corrected.

by anonymous   2018-03-19

K&R and Stroustrup are classics, and eventually you should get them, but I don't think they are good introduction for C++ beginners. Thinking in modern C++ is thinking in classes, templates, exceptions, and streams, none of which available in C language.

I would recommend a college-level textbook on C++ like Deitel and Deitel. alt text

After playing around, you should focus on learning to write a class that behaves like a built-in class. That means providing a copy constructor, operator=, operator==, operator<<, etc.. Along the way you'll meet various concepts embedded in the language of C++. I would agree with others on Effective C++ is a must read once you are comfortable with the basics.

by anonymous   2017-08-20

The short version:

In COM you should use HRESULTs (and strive to use ISupportErrorInfo, etc.) for most/all types of error conditions. The HRESULT mechanism should be viewed as a form of exception throwing. If you are familiar with that, consider "Error conditions" as anything for which you would normally throw an exception in a language that supports them. Use custom return values for things for which you would not normally use exceptions.

For example, use a failure HRESULT for invalid parameters, invalid sequence of operations, network failures, database errors, unexpected conditions such as out-of-memory, etc. On the other hand, use custom out parameters for things like 'polling, data is not ready yet', EOF conditions, maybe 'checked data and it doesn't pass validations'. There is plenty of discussions out there discussing what each should be (e.g. Stroustrup's TC++PL). The specifics will heavily depend on your particular object's semantics.

The longer version:

At a fundamental level, the COM HRESULT mechanism is just an error code mechanism which has been standardized by the infrastructure. This is mostly because COM must support a number of features such as inter-process (DCOM) and inter-threaded (Apartments) execution, system managed services (COM+), etc. The infrastructure has a need to know when something has failed, and it has a need to communicate to both sides its own infrastructure-related errors. Everybody needs to agree on how to communicate errors.

Each language and programmer has a choice of how to present or handle those errors. In C++, we typically handle the HRESULTs as error codes (although you can translate them into exceptions if you prefer error handling that way). In .NET languages, failure HRESULTs are translated into exceptions because that's the preferred error mechanism in .NET.

VB6 supports "either". Now, I know VB6's so-called exception handling has a painful syntax and limited scoping options for handlers, but you don't have to use it if you don't want to. You can always use ON ERROR RESUME NEXT and do it by hand if you think the usage pattern justifies it in a specific situation. It's just that instead of writing something like this:

statusCode = obj.DoSomething(param1)
If IS_FAILURE(statusCode) Then
    'handle error
End If

Your write it like this:

obj.DoSomething param1
IF Error.Number <> 0 Then
    'handle error
End If

VB6 is simply hiding the error code return value from the method call (and allowing the object's programmer to substitute it for a "virtual return value" via [retval]).

If you make up your own error reporting mechanism instead of using HRESULTs, you will:

  1. Spend a lot of time reinventing a rich error reporting mechanism that will probably mirror what ISupportsErrorInfo already gives you (or most likely, not provide any rich error information).
  2. Hide the error status from COM's infrastructure (which might or might not matter).
  3. Force your VB6 clients to make one specific choice out of the two options they have: they must do explicit line-by-line check, or more likely just ignore the error condition by mistake, even if they would prefer an error handler.
  4. Force your (say) C# clients to handle your errors in ways that runs contrary to the natural style of the language (to have to check every method call explicitly and... likely throw an exception by hand).
by anonymous   2017-08-20

One of the best explanation of lambda expression is given from author of C++ Bjarne Stroustrup in his book ***The C++ Programming Language*** chapter 11 (ISBN-13: 978-0321563842):

What is a lambda expression?

A lambda expression, sometimes also referred to as a lambda function or (strictly speaking incorrectly, but colloquially) as a lambda, is a simplified notation for defining and using an anonymous function object. Instead of defining a named class with an operator(), later making an object of that class, and finally invoking it, we can use a shorthand.

When would I use one?

This is particularly useful when we want to pass an operation as an argument to an algorithm. In the context of graphical user interfaces (and elsewhere), such operations are often referred to as callbacks.

What class of problem do they solve that wasn't possible prior to their introduction?

Here i guess every action done with lambda expression can be solved without them, but with much more code and much bigger complexity. Lambda expression this is the way of optimization for your code and a way of making it more attractive. As sad by Stroustup :

effective ways of optimizing

Some examples

via lambda expression

void print_modulo(const vector<int>& v, ostream& os, int m) // output v[i] to os if v[i]%m==0
        [&os,m](int x) { 
           if (x%m==0) os << x << '\n';

or via function

class Modulo_print {
         ostream& os; // members to hold the capture list int m;
         Modulo_print(ostream& s, int mm) :os(s), m(mm) {} 
         void operator()(int x) const
             if (x%m==0) os << x << '\n'; 

or even

void print_modulo(const vector<int>& v, ostream& os, int m) 
     // output v[i] to os if v[i]%m==0
    class Modulo_print {
        ostream& os; // members to hold the capture list
        int m; 
           Modulo_print (ostream& s, int mm) :os(s), m(mm) {}
           void operator()(int x) const
               if (x%m==0) os << x << '\n';

if u need u can name lambda expression like below:

void print_modulo(const vector<int>& v, ostream& os, int m)
    // output v[i] to os if v[i]%m==0
      auto Modulo_print = [&os,m] (int x) { if (x%m==0) os << x << '\n'; };

Or assume another simple sample

void TestFunctions::simpleLambda() {
    bool sensitive = true;
    std::vector<int> v = std::vector<int>({1,33,3,4,5,6,7});

         [sensitive](int x, int y) {
             printf("\n%i\n",  x < y);
             return sensitive ? x < y : abs(x) < abs(y);

    for_each(v.begin(), v.end(),
             [](int x) {
                 printf("x - %i;", x);

will generate next











0 sortedx - 1;x - 3;x - 4;x - 5;x - 6;x - 7;x - 33;

[] - this is capture list or lambda introducer: if lambdas require no access to their local environment we can use it.

Quote from book:

The first character of a lambda expression is always [. A lambda introducer can take various forms:

[]: an empty capture list. This implies that no local names from the surrounding context can be used in the lambda body. For such lambda expressions, data is obtained from arguments or from nonlocal variables.

[&]: implicitly capture by reference. All local names can be used. All local variables are accessed by reference.

[=]: implicitly capture by value. All local names can be used. All names refer to copies of the local variables taken at the point of call of the lambda expression.

[capture-list]: explicit capture; the capture-list is the list of names of local variables to be captured (i.e., stored in the object) by reference or by value. Variables with names preceded by & are captured by reference. Other variables are captured by value. A capture list can also contain this and names followed by ... as elements.

[&, capture-list]: implicitly capture by reference all local variables with names not men- tioned in the list. The capture list can contain this. Listed names cannot be preceded by &. Variables named in the capture list are captured by value.

[=, capture-list]: implicitly capture by value all local variables with names not mentioned in the list. The capture list cannot contain this. The listed names must be preceded by &. Vari- ables named in the capture list are captured by reference.

Note that a local name preceded by & is always captured by reference and a local name not pre- ceded by & is always captured by value. Only capture by reference allows modification of variables in the calling environment.


Lambda expression format

enter image description here

Additional references:

  • Wiki
  •, chapter 5.1.2
by anonymous   2017-08-20

Unfortunately, no such function exists in the C++ standard library.

If you do have access to Boost, then boost::numeric_cast should do exactly what you want. It will perform a conversion between two numeric types unless the conversion would go outside the range of the target type. In such cases, a boost::numeric::bad_numeric_cast exception is thrown.

If you were curious about implementing your own conversion, you can take a look at The C++ Programming Language 4th Edition by Bjarne Stroustrup (ISBN 978-0321563842).

In Chapter 11.5, he defines a narrow_cast as such:

template<class Target, class Source>
Target narrow_cast(Source v)
   auto r = static_cast<Target>(v); // convert the value to the target type
   if (static_cast<Source>(r)!=v)
      throw runtime_error("narrow_cast<>() failed");
   return r;

This implementation is quite bare and doesn't go quite as far as Boost's does, but could conceivably be modified to suit your needs.