Random C++ questions from a C# programmer

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
HavocVulture
Posts: 16
Joined: October 30th, 2017, 11:50 pm

Random C++ questions from a C# programmer

Post by HavocVulture » May 5th, 2020, 6:33 pm

I've recently come back to Chili's tutorials after a long while and as I'm learning I keep wondering about some aspects of C++ that seem peculiar to me.

So, in no particular order:

1.) Is there a consistent naming convention in the standard library? Is it defined somewhere?

2.) Why do names have to be fully qualified? I know you can use "using namespace std;" but it's discouraged. What I'm trying to understand here is, from a technical standpoint, why can you litter your source files in C# with using statements without issue, but it causes problems in C++? Couldn't C++ just force you to fully qualify ambiguities as in C#?

3.) A lot of the names of functions or member variables seem unintuitive. Perhaps this is due to my unfamiliarity with the language, but to provide one specific example: vector.push_back, why push_back? Why not add?

4.) Some of the standard library classes lack functionality that I would expect. For example, std::string contains no tolower/toupper functions, another example, vector has no contains function. I know some of this functionality is in algorithm, but why wouldn't it be part of the class?

Anyway, I'm trying to better understand the design philosophy of C++ and some things just look really weird to me from my C# background. I'm really enjoying the series. Chili is a very engaging teacher.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Random C++ questions from a C# programmer

Post by albinopapa » May 5th, 2020, 7:30 pm

1.) Is there a consistent naming convention in the standard library? Is it defined somewhere?
The only naming convention that I know of is all types, functions are lowercase to try and avoid collision with other programmers' code. Names beginning with _ are for standard library implementers and names beginning with __ are reserved for compiler implementations. Using this same naming scheme is considered undefined behavior.
2.) Why do names have to be fully qualified? I know you can use "using namespace std;" but it's discouraged. What I'm trying to understand here is, from a technical standpoint, why can you litter your source files in C# with using statements without issue, but it causes problems in C++? Couldn't C++ just force you to fully qualify ambiguities as in C#?
The 'using namespace std' is really only discouraged in header files because of possible naming collisions. Because source files ( .cpp files ) are or should never be #include'd it can be done in these files, though it's possible a name collision can still happen. This is the whole purpose of a namespace, to have types with the same name and avoid naming collisions. As for functions, they can be overloaded, but because of the way the compiler mangles the names of functions to avoid naming collisions or calling the wrong function they cannot have the same signature. void foo(int) and void foo(int) are the same signature even if declared in two different header files. So you must put one or both in a namespace to distinguish between the two.
3.) A lot of the names of functions or member variables seem unintuitive. Perhaps this is due to my unfamiliarity with the language, but to provide one specific example: vector.push_back, why push_back? Why not add?
The intent of push_back() in particular is to push a new item to the back of the vector. While add() to you may seem like it means the same, add alone linguistically implies a mathematical function. This has been a cause of some controversy of std::string::operator+() since + implies a mathematical function not a push char or const char* or another std::string object to the end of the current std::string.

On a side note, I agree that some instances of naming confuses me like std::vector::empty() or any of the standard containers' empty() functions. It returns true if the container is empty, which should be named std::(container)::is_empty(). At first I thought it was a statement saying ( make this container empty ), but that was what the clear() function does.

Not all of the containers have a "push_back" named function, std::queue just has a push() function for example because you can only push a value onto the queue in one place. Std::list has push_front and push_back since you can "add" to the front or back of the list in constant time. To add a new object anywhere in the containers, you can use insert() which is pretty clear what it does by the name. Push_back is just a convenience function instead of:

Code: Select all

std::vector<int> ints = { 1, 2, 3 };
ints.insert( ints.end(), 4 );
You can just write:

Code: Select all

std::vector<int> ints = {1, 2, 3};
ints.push_back( 4 );
4.) Some of the standard library classes lack functionality that I would expect. For example, std::string contains no tolower/toupper functions, another example, vector has no contains function. I know some of this functionality is in algorithm, but why wouldn't it be part of the class?
As you said, the functionality is a part of the algorithms library which extends the classes without having to write those functions for each class. One key idiom is the 'Don't Repeat Yourself". This is another controversy of std::string. Some find that the string class is way too bloated and should've just relied on the algorithms "std::find(), std::find_first_of(), ...". The tolower/toupper only do single characters, so if you wanted to transform the entire string to lower/upper case, you'd have to use something like std::transform.

Code: Select all

std::string str = {Hello, world!};
std::transform( str.begin(), str.end(), str.begin(), tolower );
The .NET framework definitely spoils programmers with it's convenience types and garbage collection. C++ is designed to be general purpose and allows the developer to go from low level bit manipulations and memory allocation and manipulation to higher level abstractions. The algorithms library allows developers to create libraries that take in iterators to containers without having to know what the containers are or their types. This allows for few lines of code that have to be written overall since you don't have to define algorithms for different types of containers with different allocators for different contained types.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Random C++ questions from a C# programmer

Post by albinopapa » May 5th, 2020, 7:40 pm

As an example for the __ naming.

The C++ language itself can't determine if a type is trivially copyable. Trivially copyable means that a type doesn't have the T& operator=( T const& ) operator overloaded because the struct/class might just have stack allocated data as opposed to heap allocated data which means a simple memcpy or memmove would work just fine. To get around this, the compiler implementations might have a function call that calls back to the compiler's AST for information about the type. The function in Visual Studio is: __is_trivially_copyable(T).
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

HavocVulture
Posts: 16
Joined: October 30th, 2017, 11:50 pm

Re: Random C++ questions from a C# programmer

Post by HavocVulture » May 5th, 2020, 7:59 pm

Thanks for the excellent response. I guess I have been spoiled by C#. It possesses a degree of orthogonality that often allows me to guess how something will work without looking it up. In fairness, C++ is much less familiar territory.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Random C++ questions from a C# programmer

Post by albinopapa » May 5th, 2020, 11:15 pm

I was unsuccessful in my getting to know C# or maybe just the .NET framework. I felt restricted or lost, but then again i never looked up any tutorials on the matter either. My point was it wasn't very intuitive to me.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply