How to deal with frustration?

Salutations all, as you could tell by the title of this topic, I'd like some advice on how to deal with the frustration of not understanding certain concepts or not being able to implement your ideas with efficiency. Sometimes I get my hands on a code exercise list so I can train my skills, but I don't even know how to read a file line by line and store them into C-style strings. Please, let me know if this post is not adequate for this forum.
Thank you all.
C++ has std::string in Standard Library. With that we do not need to handle data as C-style strings, except in rare cases.

Could you describe the other concepts that you don't understand?
Surely not everything from this list: https://en.cppreference.com/w/cpp/language


Note, C++20 has a new keyword: concept
Thank you for your answer. I can grasp the vast majority of those but few from 'Templates' and 'Exceptions'. Sometimes I understand the concepts, but cannot think of a use for them. Let's take class constructors and destructors as an example. I understand what it is, but I cannot think of a class I'd create that would have one. Another example is std::set. What are its advantages over other containers? Why so many containers? Maybe I just have some difficulty with learning and problem solving. Also, whenever a feature that was present in C is present in C++, say std::pow() from the cmath header, is it generally better practice (or generally more efficient) to use the C++ implementation over the C one, assuming it's available?
Thanks again.
Templates are generic code. "Compile-time polymorphism." Lets take the std::set. It is a template. You could have set<int>, set<Square>, set<Person>, etc. The operations that you can do for a set are same regardless of the type of the elements. Large part of C++ Standard Library is templates.


You call a function. It encounters an error that it can't handle. How does it tell you, the caller that you have error X to handle?

The called function could call exit() to quit the whole program immediately.

The string::find() returns string::npos (rather than valid index) if nothing is found: http://www.cplusplus.com/reference/string/string/find/
You have to check the return value. If you don't then undefined behaviour eats you.

The atol() does not tell in any way: http://www.cplusplus.com/reference/cstdlib/atol/
You will never know, until the undefined behaviour eats you.

The strtol() does modify global variable errno:
http://www.cplusplus.com/reference/cstdlib/strtol/
http://www.cplusplus.com/reference/cerrno/errno/
If you don't check the errno, then undefined behaviour eats you.

The stol() throws exception: http://www.cplusplus.com/reference/string/stol/
If you don't handle exceptions, the whole program quits immediately.


Have you seen "linked list" examples?
1
2
3
4
// create Node with value==42 and next==nullptr
Node* x = new Node;
x->value = 42;
x->next = nullptr

One will probably create many Nodes within functions of linked list. A lot of repetition. More chances for typos.

With a custom constructor you could achieve the same with:
1
2
// create Node with value==42 and next==nullptr
Node* x = new Node( 42 );


Worse yet:
1
2
3
4
5
const Node y;
y.value = 42; // error: cannot modify const object

const Node z( 42 ); // ok
// assert: z.value == 42 



The <cmath> is a wrapper for <math.h>. You get C's functions and some additional C++ versions. You definitely use <cmath> for all those.

C has rand(). C++ has large set of tools for creating random numbers in <random>. Use the <random>
http://www.cplusplus.com/reference/random/
That was amazingly clarifying, thank you. I'd like to ask about the use of the ternary or conditional operator. Some sources state it is bad practice to make use of it, others say otherwise. What are some examples of good and bad uses for the ternary operator?
to deal with the frustration of not understanding certain concepts or not being able to implement your ideas with efficiency


That happens to most of us at some point. Understanding the concepts is important in any language - not just C++. If you don't understand something, then there's usually plenty of info available on the Internet, in books/articles/blogs etc and by asking questions on forums like this one. Don't be fobbed off by an answer you don't understand. Ask again - or state your understanding and ask for comment. [ I've just had an 'interesting' discussion re copy/move semantics on a different thread on this site when I learnt something from JlBorges that I hadn't realised (thanks) ].

For on-line learning, have a look at https://www.learncpp.com/

The best way to learn to program is to program. The more you code, the better you usually become. Read about a new languauge feature, then write some code that uses it. If you want to achieve something, how many ways can you find to do it? Which are the 'best'?

You mention std::set. This will hold a unique value in a defined sorted order. So if you need something sorted, there's no need to perform a separate sort procedure. Also if you need unique items (eg person id) then if they are stored in a set and the one you're trying to insert already exists then you know it's not unique. etc

Maybe I just have some difficulty with learning and problem solving.


That will usually come with experience. However, one important thing that is often missing from learning resources is the concept of program design. This is where you do the thinking about the program is intended to do - and how at a highish level, its going to do it. Things like - input/output, data structures, classes, class functions, stand-alone-functions, algorithms for data processing etc etc. In plain-ish English (not C++ language!) that in detail describes how the problem could be solved using pen/paper etc. Once you have this program design, then you start to code from the design. Code a small chunk (no more than about 20 lines). Compile, get rid of any compile errors and then test. Only move on to coding the next chunk once the previous ones work as expected. As a rough 'rule of thumb' you'd typically spend about 40% - 50% of the total time on design, 10% - 20% on testing/debugging and the rest on coding. I'd suggest 40%, 40%, 20%
Last edited on
ah, two things jump out at me here.

first, the ternary operator. You see it over and over in one liners.
the idea is that instead of this:
if(something)
{
cout << "something";
}
else
{
cout << "other";
}
you just get a condensed cout << something? "something": "other";
its one of those style things. the people saying it is bad argue that it is hard to read.
the people saying it is good argue that condensed code is a good style.
Many things you will see every day have dissertations online as to why they are bad, from multiple inheritance to operator overloading to unsigned types. Yet the language supports these and each one has a place where it is powerful. C++ gives you a lot of tools, some of which are dangerous (raw pointers comes to mind) and others which are too awful to use without an unusual circumstance (goto, global variables). Often the place you work at will tell you what not to do. When you can make your own decisions, try to justify your use of 'bad' things by explaining it out loud to an imagined peer. If you can't explain why using it there was better than an alternative, then don't use it!

and the other thing that jumped out was that you see no use for some concepts.
A LOT of things are not useful for homework sized problems. They only really begin to bear fruit in larger programs that you see in production. Exceptions, for example, are very useful to trap errors and handle them (for example, say the network where the user is storing files that are open in your program goes down).

the best way to understand why templates are cool is to use vectors a bit.
I honestly very rarely use any templates I write myself, but when you need one, they are a powerful tool.
Last edited on
> the ternary operator .. its one of those style things.
> the people saying it is bad argue that it is hard to read.
> the people saying it is good argue that condensed code is a good style.

It is not just a style thing; it is a statement vs expression thing.

There are some situations where an expression is required, and can't be replaced with a statement; for instance as the initialiser used to initialise a constant.
const std::string str = a > b ? "greater" : "less" ;

There are some situations where an expression is more efficient; for instance as the initialiser of a member in a member initializer list
bergjensen33 wrote:
Let's take class constructors and destructors as an example. I understand what it is, but I cannot think of a class I'd create that would have one.


The purpose of a constructor is to initialise the member variables of the class or struct.

There are a number of ways this can happen:
1. default behavior, as in specifying default() for a constructor;
2. specifying default values for each member yourself in the class definition;
3. have your own constructor that takes arguments, and set the values of each member with a member initialiser list.

The last one is probably a quite common way of creating an object with particular values.

The first two can create an object with default values, but we want avoid doing this then set the values later: it is more efficient to use method 3 to do it all at once. Some of the STL functions such as emplace_back , call the constructor to create the object directly in the container.

With destructors it is quite common to just use the default behaviour, that is not write your own destructor. But there are times when one needs to write a destructor. One example is for a RAII class: obtain a resource in the constructor, destroy it in the destructor.

bergjensen33 wrote:
Another example is std::set. What are its advantages over other containers? Why so many containers?


Various STL containers are implemented with different data structures. Side Note: The C++ standard does not specify how a container should be implemented. Each data structure has it's own advantages and disadvantages: some are fast at finding values; some are fast at inserting at beginning or end; some of them are associative - they have a key value pair and use hash functions.

One can look on cppreference to see what the various pro and cons are :

https://en.cppreference.com/w/cpp/container

One thing to note though, there are several things which affect the performance of container operations, according to Bjarne Stroustrup: move semantics; concurrency; and cache effects.

Sometimes the performance can be surprising. I once tried the hypotheses that an std::unordered_map might be faster than a std::vector to find a value because it uses a hash function. But for anything up to 8 million ints (on my machine) the vector could create all the values, sort them, then find the value quicker than unordered map could create values and lookup using the hash function. It was JLBorges who educated me about this.

I guess the thing to realise is that programming in general is a vast field - there is a lifetime of learning. I would even go so far as to say there is a lifetime of learning just in C++, partly due to new standards and library features coming out every 3 years.

It is not enough to just learn the features of a language: one has to learn quite a bit about computer science theory; things like design patterns; idioms; good practise; the list goes on .......

With my first C++ text book, I read the whole thing over a weekend. Some of the things I learnt: overloaded functions do this; classes do this; templates do this; iterators do this etc. But that was just the barest scratch on the tip of the iceberg. For example, classes sound like a simple concept, but saying that I know what a class and inheritance is, so now I know how to do OO programming, is utterly false.

I am not trying to put you off here, plug away at learning stuff a small piece at a time. Gradually the pieces will fit together, you will feel more confident as time goes on. Ask questions here, there are plenty of people who know their stuff. We have a number of people who I consider experts.
I didn't expect to receive this many useful, patient and clarifying answers, I cannot thank you all enough.
I'd like some advice on how to deal with the frustration of not understanding certain concepts or not being able to implement your ideas with efficiency.
Learning a computer language is like learning a foreign language. When you start out, you can barely express yourself. With practice, you'll get better.

Suppose you wanted to print a message every time you enter or leave a function. A class would be handy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Trace {
public:
    Trace(const string &s) {
        str = s;
        cout << "Entering " << str << '\n';
    }
    ~Trace() {
        cout << "Leaving " << str << '\n';
private:
    string str;
};

void f() {
    Trace t("f");
    // the rest of the f()
}


Now when you enter f(), the program will print "Entering f\n" and when f returns, for any reason, it will print "Leaving f\n". f() could have 30 return statements and throw 18 exceptions and the functions it calls could throw 7 more, but no matter what (okay, almost no matter what), it will tell you when it leaves f().

Another example is std::set. What are its advantages over other containers?

An excellent and important question! Different containers have different performance for different operations. Want to look up items in collection by value? A set is a great at that, but a vector isn't. Want to get the n'th item in the collection? A vector is great at that while a set is terrible. So all of these data structures are designed to optimize particular types of operations.
@OP,

to me it sounds you want to learn too many different things at once.
First you mentioned reading a file, then classes, then set.
I would recommend to get a book and go through it slowly.
A good book about the STL and how to use it is "C++ Standard Library, The: A Tutorial and Reference 2nd Ed"
https://www.amazon.com/Standard-Library-Tutorial-Reference-2nd/dp/0321623215/ref=sr_1_1?dchild=1&keywords=josuttis+library&qid=1626026363&s=books&sr=1-1
Topic archived. No new replies allowed.